pazl-shelter
Version:
前端脱敏:用户名、手机号、邮箱、银行卡、身份证、地址、车架号、军官号、驾照号, MAC地址、公积金号、IP、社保号、车牌
301 lines (259 loc) • 7.46 kB
JavaScript
let cnReg = /[\u4E00-\u9FA5]+/; // 判断中文
// 判断是否包含中文
function isInCloudCN(str) {
return cnReg.test(str);
}
// 脱敏的公共逻辑
function createShelter(fn) {
return function (str) {
if (!str || !fn || typeof str !== 'string') {
return str;
}
str = str.trim();
return fn(str, str.length);
}
}
// 脱敏用户名
const shelterUserName = createShelter(userName => {
let newName = userName;
if (isInCloudCN(userName)) {
// 中文
let userNameReg = /(\S).+/;
if (userName.length >= 4) {
userNameReg = /(\S{2}).+/;
}
newName = userName.replace(userNameReg, '$1**')
} else {
// 其他语言
let enReg = /^.+(\s[A-Za-z]+)$/
if (enReg.test(userName)) {
newName = userName.replace(enReg, '***$1')
}
}
return newName;
})
// 脱敏手机号
const shelterPhoneNumber = createShelter(phoneNumber => {
// 去掉空格
phoneNumber = phoneNumber.replace('(', '');
phoneNumber = phoneNumber.replace(')', '');
let newPhoneNumber = phoneNumber;
let phoneReg = /^(\d{3}).+(\d{4})$/;
if (phoneNumber.length >= 6 && phoneNumber.length <= 8) {
phoneReg = /^(\d{2}).+(\d{2})$/;
}
if (phoneNumber.length >= 9 && phoneNumber.length <= 10) {
phoneReg = /^(\d{2}).+(\d{3})$/;
}
newPhoneNumber = phoneNumber.replace(phoneReg, '$1****$2');
return newPhoneNumber;
})
// 脱敏邮箱
const shelterEmail = createShelter(email => {
let ems = email.split('@');
if (ems.length < 2 || ems[0].length < 1 || ems[1].length < 0) {
return email;
}
if (ems[0].length <= 3) {
return `${ems[0]}***@${ems[1]}`;
}
if (ems[0].length > 3) {
return `${ ems[0].replace(/^(\S{3}).+$/,'$1***@')}${ems[1]}`;
}
})
// 脱敏银行卡
const shelterBankCard = createShelter(number => {
let newCard = number;
let cardReg = /(\d{6})(\d{4})/;
if (number.length > 10) {
let r = /^(\d{6}).+(\d{4})$/;
let length = number.length - 6;
if (length < 3) {
length = 3
}
let star = ''.padEnd(length, '*');
return number.replace(r, `$1${star}$2`)
} else if (number.length >= 6) {
let r = /^(\d{2}).+(\d{2})$/;
return number.replace(r, `$1****$2`)
} else {
let s = '';
number.split('').forEach((item, index) => {
s += item;
if (index == 2) {
s += '*';
}
})
return s;
}
});
// 脱敏身份证
const shelterIdCard = createShelter(number => {
let carReg = /^(\S{4}).+(\S{4})$/;
let length = number.length - 8;
let star = ''.padEnd(length, '*');
return number.replace(carReg, `$1${star}$2`)
});
// 地址脱敏
const shelterAddress = createShelter(address => {
let newAddress = address;
if (isInCloudCN(address)) {
// 中文地址
if (address.includes('市')) {
let addressArr = address.split('市');
let tempStr = '';
addressArr.forEach((item, index) => {
if (index === addressArr.length - 1) {
tempStr += ''.padEnd(item.length, '*');
} else {
tempStr += item + '市';
}
})
newAddress = tempStr;
} else {
// 如果不包含市则全部隐藏
newAddress = hideAll(address.length); // 无效地址
}
} else {
// 其他语言地址
newAddress = splitAddress(address);
}
//
function splitAddress(address) {
let length = Math.floor(address.length / 2);
return address.slice(0, length) + ''.padEnd(length, '*');
}
return newAddress;
});
// 脱敏车架号
const shelterCarNumber = number => shelterIdCard(number);
// 军官号、车架号
const showLastTwoNumber = createShelter( number => {
let length = number.length - 2;
let reg = /^\S+(\S{2})$/;
return number.replace(reg, `${''.padEnd(length, '*')}$1`);
})
//驾照号码
const driverlicenseNumber = createShelter( number => {
let length = number.length;
if (length >= 15) {
return shelterIdCard(number);
} else {
let reg = /^(\S+)(\S{5})$/;
return number.replace(reg, `$1****`);
}
});
// 公积金
const accumulationFundNumber = createShelter((number, len) => {
let reg = /^(\S+)(\S{5})$/;
let starLen = 5;
if (len > 9) {
reg = /^(\S+)(\S{7})$/
starLen = 7
}
return number.replace(reg, `$1${''.padEnd(starLen, '*')}`);
});
// 社保号
const socialSecurityNumber = createShelter((number, len) => {
if (len >= 15) {
return shelterIdCard(number);
} else {
let reg = /^(\S{2})(\S+)(\S{2})$/;
let starLen = len - 4;
starLen < 0 ? starLen = 0: '';
return number.replace(reg, `$1${''.padEnd(starLen, '*')}$3`)
}
})
// ip
const ipNumber = createShelter((number) => {
let reg = /^(\d+)(.\d+)(.\d+)(.\d+)$/;
return number.replace(reg, '$1$2******');
});
// 全部屏蔽 IMEI IDFA
const hideAll =len=> ''.padEnd(len, '*');
// 车牌号
const plateNumber = createShelter((number, len) => {
number = number.replace(' ', '').replace(' ', '')
let reg = /^(\S{3})\S+(\S{1})$/;
return number.replace(reg, `$1${''.padEnd(len-4, '*')}$2`);
})
/**
* 1: 用户名
* 2: 手机号
* 3: 邮箱
* 4: 银行卡
* 5: 身份证
* 6: 地址
* 7: 车架号
* 8: 军官号、护照号、居住证
* 9: 驾照号, MAC地址
* 10: 公积金号
* 11: 社保号
* 12:IP
* 13:车牌号
*/
const fnName = {
1: shelterUserName,
2: shelterPhoneNumber,
3: shelterEmail,
4: shelterBankCard,
5: shelterIdCard,
6: shelterAddress,
7: shelterCarNumber,
8: showLastTwoNumber,
9: driverlicenseNumber,
10: accumulationFundNumber,
11: socialSecurityNumber,
12: ipNumber,
13: plateNumber
}
// 封装一个通用的脱敏方法
const shelter = (str, type) => {
if (!str || !type) {
console.error('哦吼,脱敏参数不完整!')
return str;
} else {
let fn = fnName[type];
if (!fn || typeof fn !== 'function') {
console.error('哦吼,type 取值区间:1-7!')
return str;
} else {
return fn(str);
}
}
}
/**
* @description: 脱敏对象的部分key
* @param { Object} obj 要脱单对象
* @param { string} keys 要脱的key的集合 ,例:[{key: 'userName', type: 1}, { key: 'phone', type: 2}]
* @returns { Object} 脱敏后的对象
*/
const shelterObj = function (obj, keys) {
keys.forEach(item => {
obj[item.key] = shelter(obj[item.key], item.type);
})
return obj;
}
/**
* @description: 数组批量脱敏[表格数据]
* @param {Array} arr 要脱敏的数组
* @param {string} keys 要脱的key的集合 例:[{key: 'userName', type: 1}, { key: 'phone', type: 2}]
* @returns { Object} 脱敏后的列表
*/
const shelterArr = function (arr, keys) {
return arr.map(item => {
return shelterObj(item, keys);
})
}
module.exports = {
shelter,
shelterObj,
shelterArr,
shelterUserName,
shelterPhoneNumber,
shelterEmail,
shelterBankCard,
shelterIdCard,
shelterAddress,
shelterCarNumber
}