线上一直在使用的身份证校验, 经过线上问题反馈不断优化完善了以下几点。
- 年份的处理:第七位到第十位是年份,这两位可以是19或者20,处理了更早或更晚的年份。考虑到身份证的合法性,应考虑年份的合理范围,如1920-2099。
- 月份的处理:第十一位和第十二位是月份,处理01-12已经很完善。
- 日期的处理:第十三位和第十四位是日期,从01-31之间的数值,尚未处理2月份的闰年与平年及不同月份天数的情况。
- 正则表达式的简化:可以简化以提高可读性。
function checkIDCard(idcode) {
// 加权因子
var weight_factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
// 校验码
var check_code = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
var code = idcode + '';
var last = code[17]; //最后一位
var seventeen = code.substring(0, 17);
// ISO 7064:1983.MOD 11-2
// 判断最后一位校验码是否正确
var arr = seventeen.split('');
var len = arr.length;
var num = 0;
for (var i = 0; i < len; i++) {
num = num + arr[i] * weight_factor[i];
}
// 获取余数
var resisue = num % 11;
var last_no = check_code[resisue];
// 格式的正则
var idcard_patter =
/^[1-9]\d{5}(19\d{2}|20[0-9]{2})(0[1-9]|1[0-2])(0[1-9]|[1-2]\d|3[0-1])\d{3}(\d|X)$/;
// 判断格式是否正确
var format = idcard_patter.test(idcode);
// 容错
var failIdcard = '632721201307070036';
var result = failIdcard === idcode;
// 返回验证结果,校验码和格式同时正确才算是合法的身份证号码
return (last === last_no && format) || result;
}