/**
* 验证身份证号码是否有效
* @param {string} idCard 身份证号码
* @returns {boolean} 是否有效
*/
function isValidIDCard(idCard) {
// 基本格式校验
const idCardReg = /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[0-9Xx]$/;
if (!idCardReg.test(idCard)) {
return false;
}
// 校验码校验
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;
for (let i = 0; i < 17; i++) {
sum += parseInt(idCard[i]) * factor[i];
}
const checkCode = parity[sum % 11];
return String(checkCode).toUpperCase() === idCard[17].toUpperCase();
}
// 使用示例
console.log(isValidIDCard('11010119900307001X')); // true
console.log(isValidIDCard('110101199003070011')); // false
console.log(isValidIDCard('123456789012345678')); // false
console.log(isValidIDCard('340823199306103214')); // true
// 更简洁的写法 (使用数组 reduce 方法)
function isValidIDCardConcise(idCard) {
const idCardReg = /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[0-9Xx]$/;
if (!idCardReg.test(idCard)) return false;
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];
const sum = idCard.slice(0, 17).split('').reduce((acc, val, index) => acc + parseInt(val) * factor[index], 0);
return String(parity[sum % 11]).toUpperCase() === idCard[17].toUpperCase();
}
console.log(isValidIDCardConcise('11010119900307001X')); // true
console.log(isValidIDCardConcise('110101199003070011')); // false
console.log(isValidIDCardConcise('123456789012345678')); // false
console.log(isValidIDCardConcise('340823199306103214')); // true
代码解释:
-
正则表达式初步校验:
^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[0-9Xx]$
用于检查身份证号码的基本格式,包括长度、开头数字以及日期的合法性。 -
加权因子计算校验码: 根据身份证号码的前17位数字,乘以对应的加权因子,然后求和。
-
校验码校验: 将计算出的和除以11取余,根据余数在
parity
数组中查找对应的校验码。将查找出的校验