一般正则校验不够严谨,只能比较泛泛,有的只校验长度
常规正则:/^(\d){17}([0-9xX])$/.test(code)
// code 身份证号码
本校验可以校验:格式、省市区、年龄、年月日、平闰年算法、末位校验
废话不多说,看代码:
const WI = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1];
const VI = [1, 0, "X", 9, 8, 7, 6, 5, 4, 3, 2];
const AI = [];
const AREA_CODE = ["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"];
const DAYS = [31, undefined, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
const dateMap = new Map();
const areaCodeMap = new Map();
let message = "";
(() => {
dateMap.clear();
DAYS.forEach((value, index) =>
dateMap.set(`${index > 8 ? index + 1 : "0" + (index + 1)}`, value)
);
areaCodeMap.clear();
AREA_CODE.forEach((value) => areaCodeMap.set(value, undefined));
})();
function verifyCodeType(code) {
if (typeof code === "undefined" || code === null || `${code}`.length < 1) {
message = "错误:未输入身份证号码";
return false;
}
return true;
}
function verifyLength(code) {
if (`${code}`.length !== 18) {
message = "错误:身份证号码不是 18 位";
return false;
}
return true;
}
function verifyRegex(code) {
if (!/^(\d){17}([0-9xX])$/.test(code)) {
message = "错误:身份证号码格式不正确";
return false;
}
return true;
}
function verifyAreaCode(code) {
const areaCode = `${code}`.substr(0, 2);
if (!areaCodeMap.has(areaCode)) {
message = `错误:输入的身份证号的地区码(1-2 位)[${areaCode}] 不符合中国行政区划分代码规定 (GB/T2260-1999)`;
return false;
}
return true;
}
function verifyBirthdayCode(code) {
const year = parseInt(code.substr(6, 4));
const month = code.substr(10, 2);
const day = parseInt(code.substr(12, 2));
const currYear = new Date().getFullYear();
const compareYear = 2021;
const maxYear = Math.max(currYear, compareYear);
if (year < 1900 || year > maxYear) {
message = `错误:输入的身份证号(7-10 位)[${year}] 不符合要求`;
return false;
}
if (!dateMap.has(month)) {
message = `错误:输入的身份证号(11-12 位)"不存在[${month}]月份,不符合要求(GB/T7408)`;
return false;
}
const maxDay = dateMap.get(month);
if (maxDay) {
if (day > maxDay || day < 1) {
message = `错误:输入的身份证号(13-14位)[${day}] 不符合小月 1-30 天、大月 1-31 天的规定(GB/T7408)`;
return false;
}
} else {
if (year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0)) {
if (day > 29 || day < 1) {
message = `错误:输入的身份证号(13-14位)[${day}] 在闰年的情况下不符合 1-29 天的规定(GB/T7408)`;
return false;
}
} else {
if (day > 28 || day < 1) {
message = `错误:输入的身份证号(13-14位)[${day}] 在闰年的情况下不符合 1-28 天的规定(GB/T7408)`;
return false;
}
}
}
return true;
}
function getVerify(code) {
let remaining = 0;
const temp = code.substr(0, 17);
let sum = 0;
[...temp].forEach((value, index) => {
AI[index] = parseInt(value);
sum += WI[index] * AI[index];
});
remaining = sum % 11;
return remaining === 2 ? "X" : VI[remaining] + "";
}
function verifyMOD(code) {
const verifyCode = code.substr(-1).toUpperCase();
if (verifyCode === getVerify(code)) return true;
message = `错误:输入的身份证号最末尾的数字验证码错误`;
return false;
}
function verify(code) {
message = "";
const tempCode = `${code}`.trim()
if (!verifyCodeType(tempCode)) return false;
if (!verifyLength(tempCode)) return false;
if (!verifyRegex(tempCode)) return false;
if (!verifyAreaCode(tempCode)) return false;
if (!verifyBirthdayCode(tempCode)) return false;
if (!verifyMOD(tempCode)) return false;
return true;
}
export { verify as verifyIDCard, message as IDCardErrorMessage };
调用:
//引用:
import {verifyIDCard, IDCardErrorMessage} from './tool.js';
//使用:号码字符串--正常 、数字--不正常
console.log(verifyIDCard("111111111111111111"), IDCardErrorMessage)
//说明:
verifyIDCard("xxx"):返回true 或者false 用于判断是否通过校验。xxx 为字符串
IDCardErrorMessage:返回错误时,对应的提示
到处,校验已经完结。比常规校验要全面,缺点是有点长。有资格的公司可以调用工安系统校验,有点费,将近一块钱一次,但是比较准确能匹配到名字和号码。