Просмотр исходного кода

脱敏函数拓充手机号校验

htc 14 часов назад
Родитель
Сommit
bff353e42e
1 измененных файлов с 105 добавлено и 7 удалено
  1. 105 7
      utils/reg.js

+ 105 - 7
utils/reg.js

@@ -290,13 +290,111 @@ function desensitizeContent(content, type = 1) {
 
     // 2 - 手机号脱敏
     case 2: {
-      // 手机号基本校验:11位数字,以1开头
-      const phoneReg = /^1\d{10}$/;
-      if (!phoneReg.test(trimContent) || trimContent.length !== 11) {
-        return content; // 不符合手机号格式返回原内容
-      }
-      // 保留前3位和后4位,中间4位用*代替
-      return trimContent.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
+		// 定义不同区号的手机号脱敏规则映射表
+		const phoneDesensitizeRules = {
+		 // 中国及港澳台
+		   '+86': [3, 4, '+86', 11],      // 中国大陆:11位,前3后4(138****8000)
+		   '+852': [2, 4, '+852', 8],     // 中国香港:8位,前2后4(12****78)
+		   '+853': [2, 4, '+853', 8],     // 中国澳门:8位,前2后4(12****78)
+		   '+886': [3, 4, '+886', 10],    // 中国台湾:10位,前3后4(098****7890)
+		   
+		   // 亚洲
+		   '+81': [3, 4, '+81', 11],      // 日本:11位,前3后4(090****1234)
+		   '+82': [3, 4, '+82', 11],      // 韩国:11位,前3后4(010****1234)
+		   '+65': [2, 4, '+65', 8],       // 新加坡:8位,前2后4(61****78)
+		   '+60': [3, 4, '+60', 10],      // 马来西亚:10位,前3后4(012****7890)
+		   '+91': [3, 4, '+91', 10],      // 印度:10位,前3后4(987****6543)
+		   '+66': [3, 4, '+66', 10],      // 泰国:10位,前3后4(081****1234)
+		   '+84': [3, 4, '+84', 10],      // 越南:10位,前3后4(091****1234)
+		   '+92': [3, 4, '+92', 11],      // 巴基斯坦:11位,前3后4(0300****1234)
+		   '+94': [3, 4, '+94', 10],      // 斯里兰卡:10位,前3后4(771****1234)
+		   '+880': [3, 4, '+880', 11],    // 孟加拉国:11位,前3后4(0171****1234)
+		   '+62': [3, 4, '+62', 12],      // 印度尼西亚:12位,前3后4(0812****1234)
+		   '+966': [3, 4, '+966', 9],     // 沙特阿拉伯:9位,前3后4(500****123)
+		   '+971': [2, 4, '+971', 9],     // 阿联酋:9位,前2后4(50****1234)
+		   '+965': [2, 4, '+965', 8],     // 科威特:8位,前2后4(50****123)
+		   '+974': [2, 4, '+974', 8],     // 卡塔尔:8位,前2后4(50****123)
+		   '+95': [2, 4, '+95', 9],       // 缅甸:9位,前2后4(90****1234)
+		   '+855': [3, 4, '+855', 9],     // 柬埔寨:9位,前3后4(012****123)
+		   
+		   // 北美洲
+		   '+1': [3, 4, '+1', 10],        // 美国/加拿大:10位,前3后4(123****7890)
+		   '+52': [3, 4, '+52', 10],      // 墨西哥:10位,前3后4(123****7890)
+		   
+		   // 欧洲
+		   '+44': [3, 4, '+44', 11],      // 英国:11位,前3后4(791****1234)
+		   '+33': [3, 4, '+33', 10],      // 法国:10位,前3后4(601****1234)
+		   '+49': [3, 4, '+49', 11],      // 德国:11位,前3后4(151****12345)
+		   '+34': [2, 4, '+34', 9],       // 西班牙:9位,前2后4(60****1234)
+		   '+39': [3, 4, '+39', 10],      // 意大利:10位,前3后4(333****1234)
+		   '+32': [2, 4, '+32', 9],       // 比利时:9位,前2后4(47****1234)
+		   '+31': [2, 4, '+31', 9],       // 荷兰:9位,前2后4(61****1234)
+		   '+46': [3, 4, '+46', 10],      // 瑞典:10位,前3后4(701****1234)
+		   '+41': [2, 4, '+41', 9],       // 瑞士:9位,前2后4(79****1234)
+		   '+358': [2, 4, '+358', 9],     // 芬兰:9位,前2后4(40****1234)
+		   '+45': [2, 4, '+45', 8],       // 丹麦:8位,前2后4(12****78)
+		   '+30': [3, 4, '+30', 10],      // 希腊:10位,前3后4(690****1234)
+		   '+36': [2, 4, '+36', 9],       // 匈牙利:9位,前2后4(30****1234)
+		   '+359': [2, 4, '+359', 9],     // 保加利亚:9位,前2后4(88****1234)
+		   '+380': [3, 4, '+380', 10],    // 乌克兰:10位,前3后4(067****1234)
+		   '+7': [3, 4, '+7', 11],        // 俄罗斯/哈萨克斯坦:11位,前3后4(916****12345)
+		   '+381': [3, 4, '+381', 10],    // 塞尔维亚:10位,前3后4(630****1234)
+		   
+		   // 大洋洲
+		   '+61': [3, 4, '+61', 9],       // 澳大利亚:9位,前3后4(400****123)
+		   '+64': [3, 4, '+64', 9],       // 新西兰:9位,前3后4(210****123)
+		   
+		   // 非洲
+		   '+27': [3, 4, '+27', 10],      // 南非:10位,前3后4(082****1234)
+		   '+234': [3, 4, '+234', 11],    // 尼日利亚:11位,前3后4(080****12345)
+		   '+254': [2, 4, '+254', 9],     // 肯尼亚:9位,前2后4(70****1234)
+		   '+20': [3, 4, '+20', 10],      // 埃及:10位,前3后4(010****1234)
+		   
+		   // 南美洲
+		   '+55': [3, 4, '+55', 11],      // 巴西:11位,前3后4(119****12345)
+		   '+54': [3, 4, '+54', 10],      // 阿根廷:10位,前3后4(112****1234)
+		   '+57': [3, 4, '+57', 10],      // 哥伦比亚:10位,前3后4(300****1234)
+		};
+  
+		// 步骤1:解析手机号(区分带区号/不带区号)
+		let areaCode = '+86'; // 默认中国大陆区号
+		let purePhone = trimContent;
+  
+		// 匹配是否包含国际区号(+开头,1-3位数字)
+		const areaCodeMatch = trimContent.match(/^(\+\d{1,3})(\d+)$/);
+		if (areaCodeMatch) {
+		  areaCode = areaCodeMatch[1]; // 提取区号(如+86)
+		  purePhone = areaCodeMatch[2]; // 提取纯手机号(不含区号)
+		} else {
+		  // 无区号时,默认按+86处理,且要求是11位数字
+		  if (!/^\d{11}$/.test(trimContent)) {
+			return content; // 无区号且不是11位数字,返回原内容
+		  }
+		}
+  
+		// 步骤2:获取当前区号的脱敏规则,无规则则用默认逻辑
+		const rule = phoneDesensitizeRules[areaCode] || [3, 4, areaCode, purePhone.length];
+		const [keepPrefix, keepSuffix, code, phoneLen] = rule;
+  
+		// 步骤3:校验手机号格式(位数匹配)
+		if (purePhone.length !== phoneLen) {
+		  return content; // 位数不匹配,返回原内容
+		}
+  
+		// 步骤4:执行脱敏逻辑
+		// 计算需要隐藏的位数
+		const hideLength = purePhone.length - keepPrefix - keepSuffix;
+		if (hideLength <= 0) {
+		  return content; // 无隐藏位数,返回原内容
+		}
+		// 拼接脱敏后的手机号
+		const prefix = purePhone.substring(0, keepPrefix);
+		const suffix = purePhone.substring(purePhone.length - keepSuffix);
+		const hidden = '*'.repeat(hideLength);
+		const desensitizedPhone = `${prefix}${hidden}${suffix}`;
+  
+		// 步骤5:返回带区号的脱敏结果(如果有区号)
+		return areaCodeMatch ? `${code}${desensitizedPhone}` : desensitizedPhone;
     }
 
     // 3 - 姓名脱敏