身份证验证相关
匹配身份证
新的18位身份证号码各位的含义:
1-2位省、自治区、直辖市代码;
3-4位地级市、盟、自治州代码;
5-6位县、县级市、区代码;
7-14位出生年月日,比如19670401代表1967年4月1日;
15-17位为顺序号,其中17位男为单数,女为双数;
18位为校验码,0-9和X,由公式随机产生。
15位身份证号码各位的含义:
1-2位省、自治区、直辖市代码;
3-4位地级市、盟、自治州代码;
5-6位县、县级市、区代码;
7-12位出生年月日,比如670401代表1967年4月1日,这是和18位号码的第一个区别;
13-15位为顺序号,其中15位男为单数,女为双数;
/(^\d{15}$)|(^\d{17}(\d|X)$)/
/** 18位验证 **/
/^[1-9]\d{5}(18|19|([23]\d))\d{2}(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])\d{3}[0-9Xx]$/
解析
[1-9]\d{5} 省市区 由非零数字开头
(18|19|([23]\d)) 年 1800~3999
(0[1-9]|1[0-2]) 出生月份 由01~12月格式表示;
(0[1-9]|[12][0-9]|3[01]) 出生日期 由01~31日格式表示;
\d{3} 三位顺序码的 三位顺序码的最后一位 奇数表示男性,偶数表示女性;
[0-9Xx] 校验码 是根据前17位数字根据ISO 7064:1983.MOD11-2校验码计算出的。
/** 15位验证 **/
/^[1-9]\d{5}\d{2}(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])\d{3}$/
解析
[1-9]\d{5} 省市区 由非零数字开头
\d{2} 年份后两位
(0[1-9]|1[0-2]) 出生月份 由01~12月格式表示
(0[1-9]|[12][0-9]|3[01]) 出生日期 由01~31日格式表示
\d{3} 三位顺序码
计算身份证最后一位
const cardlast = (cardNo: any) => {
let sum = 0;
const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
const codes = '10X98765432';
for (let i = 0; i < cardNo.length - 1; i++) {
sum += cardNo[i] * weights[i];
}
const last = codes[sum % 11]; //计算出来的最后一位身份证号码
return last;
};
15位转18位
const lastNumber = cardlast(cardNo.replace(/^(\d{6})(\d{6})(\d{3})$/, '$119$2$3X')); //获取最后一位
newCardNo = cardNo.replace(/^(\d{6})(\d{6})(\d{3})$/, `$119$2$3${lastNumber}`);
身份证号验证实例
<ProFormText
label="证件号"
name="cardNo"
width={'100%'}
rules={[
{
required: true,
message: '',
},
{
validator: (rule, value) => {
if (value == '') {
return Promise.reject('请输入证件号');
}
if (value.length != 15 && value.length != 18) {
return Promise.reject('身份证号码格式不正确');
}
if (value.length == 18) {
const reg1 = /^[1-9]\d{5}(18|19|([23]\d))\d{2}(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])\d{3}[0-9Xx]$/;
if (!reg1.test(value)) {
return Promise.reject('身份证号码格式不正确');
}
// 验证最后一位
if (cardlast(value) != value[value.length - 1]) {
return Promise.reject('身份证号码格式不正确');
}
return Promise.resolve();
}
if (value.length == 15) {
const reg1 = /^[1-9]\d{5}\d{2}(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])\d{3}$/;
if (!reg1.test(value)) {
return Promise.reject('身份证号码格式不正确');
}
}
return Promise.resolve();
},
},
]}
/>
获取身份证信息
/**
* 获取身份证信息
*/
export const getcardNumberInfo = (cardNo: any = "") => {
if (cardNo.length != 18 && cardNo.length != 15) {
return {};
}
let newCardNo = cardNo;
// 15位转18位
if (cardNo.length == 15) {
const lastNumber = cardlast(
cardNo.replace(/^(\d{6})(\d{6})(\d{3})$/, "$119$2$3X")
); //获取最后一位
newCardNo = cardNo.replace(
/^(\d{6})(\d{6})(\d{3})$/,
`$119$2$3${lastNumber}`
);
}
const infos: any = {};
// 获取省市区 provincesList:省市区树形列表
const province = newCardNo.slice(0, 2);
const provinces: any =
provincesList.find((item1: any) => item1?.code == province) || {};
const flatProvinces: any = getFlatTreeNodes(provinces);
infos.province = provinces?.name;
infos.city = flatProvinces.find(
(item1: any) => item1?.code == cardNo.slice(0, 4)
)?.name;
infos.district = flatProvinces.find(
(item1: any) => item1?.code == cardNo.slice(0, 6)
)?.name;
// 获取出生年月日
const birth = newCardNo.replace(
/^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([\dX])$/,
"$2-$3-$4"
);
const birthReg = /^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/;
if (birthReg.test(birth)) {
infos.birth = birth;
// 获取年龄
const birthDate = new Date(birth);
const last1 = cardNo.replace(/(\d{16})(\d{1})([\dX]{1})/, "$2") || "";
infos.sex = last1 % 2 == 0 ? "女" : "男";
const age = new Date().getFullYear() - birthDate.getFullYear();
infos.age = age > 0 ? age : "";
}
return infos;
};