222 lines
5.1 KiB
JavaScript
222 lines
5.1 KiB
JavaScript
const num = /^[0-9]*$/;
|
||
const mobile = /^1[3|4|5|6|7|8|9][0-9]\d{8}$/;
|
||
const email = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
|
||
const realName = /^[\u4e00-\u9fa5]{2,5}$/;
|
||
const num_en = /^[0-9a-zA-Z]{6,16}$/;
|
||
const name = /^\S{2,32}$/;
|
||
const identifyNumber = /^[a-zA-Z0-9]{1,20}$/;
|
||
const passwordRegExp = /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,16}$/;
|
||
|
||
const idTransfer = (sId) => {
|
||
if (sId.length === 15) {
|
||
const arrInt = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2],
|
||
arrCh = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
|
||
let nTemp = 0;
|
||
|
||
sId = sId.substr(0, 6) + '19' + sId.substr(6, sId.length - 6);
|
||
|
||
for (let i = 0; i < 17; i++) {
|
||
nTemp += Number(sId.substr(i, 1)) * arrInt[i];
|
||
}
|
||
sId += arrCh[nTemp % 11];
|
||
}
|
||
return sId;
|
||
};
|
||
|
||
const validate = {
|
||
isPasswordValid: (str) => {
|
||
return passwordRegExp.test(str);
|
||
},
|
||
isNumber: (str) => {
|
||
return num.test(str);
|
||
},
|
||
isidentifyNumber: (str) => {
|
||
return identifyNumber.test(str);
|
||
},
|
||
|
||
//是否是手机
|
||
isMobile: (str) => {
|
||
return mobile.test(str);
|
||
},
|
||
|
||
//是否是邮件
|
||
isEmail: (str) => {
|
||
return email.test(str);
|
||
},
|
||
|
||
//是否是名字(2-5)中文
|
||
varisRealName: (str) => {
|
||
return realName.test(str);
|
||
},
|
||
|
||
//是否是数字加英文
|
||
isNumEn: (str) => {
|
||
return num_en.test(str);
|
||
},
|
||
|
||
// 2-32位字符
|
||
isName: (str) => {
|
||
return name.test(str);
|
||
},
|
||
|
||
//复杂的判定身份证
|
||
isChinaId: (s) => {
|
||
const sId = idTransfer(s),
|
||
aCity = {
|
||
11: '北京',
|
||
12: '天津',
|
||
13: '河北',
|
||
14: '山西',
|
||
15: '内蒙古',
|
||
21: '辽宁',
|
||
22: '吉林',
|
||
23: '黑龙江 ',
|
||
31: '上海',
|
||
32: '江苏',
|
||
33: '浙江',
|
||
34: '安徽',
|
||
35: '福建',
|
||
36: '江西',
|
||
37: '山东',
|
||
41: '河南',
|
||
42: '湖北 ',
|
||
43: '湖南',
|
||
44: '广东',
|
||
45: '广西',
|
||
46: '海南',
|
||
50: '重庆',
|
||
51: '四川',
|
||
52: '贵州',
|
||
53: '云南',
|
||
54: '西藏 ',
|
||
61: '陕西',
|
||
62: '甘肃',
|
||
63: '青海',
|
||
64: '宁夏',
|
||
65: '新疆',
|
||
71: '台湾',
|
||
81: '香港',
|
||
82: '澳门',
|
||
91: '国外 '
|
||
};
|
||
if (!/^\d{17}(\d|x)$/i.test(sId)) {
|
||
return [false, '证件号格式错误'];
|
||
}
|
||
|
||
if (!aCity[parseInt(sId.substr(0, 2), 10)]) {
|
||
return [false, '身份证前两位错误'];
|
||
}
|
||
|
||
let sBirthday =
|
||
sId.substr(6, 4) +
|
||
'-' +
|
||
Number(sId.substr(10, 2)) +
|
||
'-' +
|
||
Number(sId.substr(12, 2));
|
||
const d = new Date(sBirthday.replace(/-/g, '/'));
|
||
|
||
if (
|
||
sBirthday !==
|
||
d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate()
|
||
) {
|
||
return [false, '非法身份证号'];
|
||
}
|
||
|
||
const sMouth = d.getMonth() + 1,
|
||
sDate = d.getDate();
|
||
sBirthday =
|
||
d.getFullYear() +
|
||
'-' +
|
||
(sMouth > 9 ? sMouth : '0' + sMouth) +
|
||
'-' +
|
||
(sDate > 9 ? sDate : '0' + sDate);
|
||
|
||
/*十八位身份证的校验码*/
|
||
// for (let i = 17; i >= 0; i--) {
|
||
// iSum += (Math.pow(2, i) % 11) * parseInt(sId.charAt(17 - i), 11);
|
||
// if ( iSum % 11 !== 1 ) {
|
||
// return [false,'非法身份证号'];
|
||
// }
|
||
// }
|
||
if (sId.length == 18) {
|
||
//∑(ai×Wi)(mod 11)
|
||
//加权因子
|
||
const factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
|
||
//校验位
|
||
const parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2];
|
||
let sum = 0;
|
||
let ai = 0;
|
||
let wi = 0;
|
||
for (let i = 0; i < 17; i++) {
|
||
ai = Number(sId[i]);
|
||
wi = factor[i];
|
||
sum += ai * wi;
|
||
}
|
||
const last = parity[sum % 11];
|
||
if (last != sId[17].toUpperCase()) {
|
||
return [false, '非法身份证号'];
|
||
}
|
||
}
|
||
|
||
return [true, sBirthday, Number(sId.substr(16, 1)) % 2 ? 'MALE' : 'FEMALE'];
|
||
},
|
||
|
||
getAge: (identityCard) => {
|
||
const len = (identityCard + '').length;
|
||
if (len == 0) {
|
||
return 0;
|
||
} else {
|
||
if (len != 15 && len != 18) {
|
||
//身份证号码只能为15位或18位其它不合法
|
||
return 0;
|
||
}
|
||
}
|
||
let strBirthday = '';
|
||
if (len == 18) {
|
||
//处理18位的身份证号码从号码中得到生日和性别代码
|
||
strBirthday =
|
||
identityCard.substr(6, 4) +
|
||
'/' +
|
||
identityCard.substr(10, 2) +
|
||
'/' +
|
||
identityCard.substr(12, 2);
|
||
}
|
||
if (len == 15) {
|
||
strBirthday =
|
||
'19' +
|
||
identityCard.substr(6, 2) +
|
||
'/' +
|
||
identityCard.substr(8, 2) +
|
||
'/' +
|
||
identityCard.substr(10, 2);
|
||
}
|
||
//时间字符串里,必须是“/”
|
||
const birthDate = new Date(strBirthday);
|
||
const nowDateTime = new Date();
|
||
let age = nowDateTime.getFullYear() - birthDate.getFullYear();
|
||
const birthMonth = identityCard.substring(10, 12);
|
||
let month = nowDateTime.getMonth() - Number(birthMonth);
|
||
//再考虑月、天的因素;.getMonth()获取的是从0开始的,这里进行比较,不需要加1
|
||
if (
|
||
nowDateTime.getMonth() < birthDate.getMonth() ||
|
||
(nowDateTime.getMonth() == birthDate.getMonth() &&
|
||
nowDateTime.getDate() < birthDate.getDate())
|
||
) {
|
||
age--;
|
||
month = 12 + month;
|
||
}
|
||
return `${age}`;
|
||
},
|
||
noOtherStr(str) {
|
||
const pattern = new RegExp(
|
||
"[`~!@#$^&*()=|{}':;',\\[\\].<>/?~!@#¥……&*()——|{}【】‘;:”“'。,、?%+_]"
|
||
);
|
||
let specialStr = '';
|
||
for (let i = 0; i < str.length; i++) {
|
||
specialStr += str.substr(i, 1).replace(pattern, '');
|
||
}
|
||
return specialStr;
|
||
}
|
||
};
|
||
|
||
export default validate; |