前言
首先身份证的全称是“中华人民共和国居民身份证”,总过经历过两代换革, 第一代是1984年发布,第二代是2004年1月1日正式发行,同时象征着第一代身份证逐步退出舞台。
二代身份证号码规则
1999年10月1日,中华人民共和国国务院批准建立了公民身份号码制度,设置出生时编排的终身不变的唯一的18位代码为公民身份号码。
18位号码规则如下
说明:
身份证号码是由18位数字组成,分别表示:
第1、2位数字表示:所在省份的代码;
第3、4位数字表示:所在城市的代码;
第5、6位数字表示:所在区县的代码;
第7-14位数字表示:出生年、月、日(其中7、8、9、10位是年,11、12位是月,13、14位是日);
第15-17位都是同一地址辖区内的,以及同年同月同日出生人的顺序码,同时第17位兼具性别标识功能,男单女双;
第18位数字是校检码:可以是0-9的数字,有时也用X表示。X是罗马数字的10,用X来代替10,可以保证公民身份证符合国家标准
JS 有效身份证号校验(二代身份证号)
/**
* @param idcode 身份证号 string类型
* @return boolean 是否合法
**/
function checkIDCard(idcode) {
/**
* 第18位数字(又叫校检码)计算公式
* 1. 求和sum:取身份证号[0~17]位数字与weight_factor[7~2]内相同下标数值乘积并求和,
* 示例:身份证号为110..2X,则公式为1*7+1*9+0*10+...2*2;
* 2. 余数z:得到 sum 除以 11 的余数,即:z = sum % 11
* 3. 校检码last_no,公式为 last_no = (12 - z) % 11,如果余数为10则为X
**/
//加权因子(该序列的由来,感兴趣自行百度)
const weight_factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
let code = idcode + "";//转成string
let last = idcode[17]; // 取出校检码
let seventeen = code.substring(0, 17);//取前17位数字,依次与weight_factor对应下标数字相乘并求和
//判断最后一位校验码是否正确
let arr = seventeen.split("");
let sum = 0;
for(let i = 0; i < arr.length; i++) {
sum = sum + arr[i] * weight_factor[i];
}
//获取余数
let resisue = sum % 11;
//获取公式计算出来的第18位数字(又叫校检码)
//方式1:利用公式计算
let last_no = (12 - resisue) % 11;
last_no = last_no + "";
if(last_no === '10') {
last_no = 'X'
}
//方式2:利用提前计算好的10位校验码序列(网上很多),直接取对应下标值即可
//const check_code = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
//let last_no = check_code[resisue];
/**
* 正则说明
* 第一位不可能是0
* 第二位到第六位可以是0-9
* 第七位到第十位是年份,所以七八位是19或者20,当七八九位是202时 第10位仅能是0-3内数值
* 第十一位、十二位是月份,数值在[01, 12]之间
* 第十三位、十四位是日期,数值在[01,31]之间
* 第十五位到第十七位可以是0-9,其中第十七位代表性别:男单数、女双数
* 第十八位(又叫校检码)可以是0-9、X
**/
const idcard_patter = /^[1-9][0-9]{5}([1][9][0-9]{2}|[2][0][0|1][0-9]|[2][0][2][0-3])([0][1-9]|[1][0|1|2])([0][1-9]|[1|2][0-9]|[3][0|1])[0-9]{3}([0-9]|[x])$/
//const idcard_patter = /^[1-9][0-9]{5} ([1][9][0-9]{2}|[2][0][0|1][0-9]|[2][0][2][0-3]) ([0][1-9]|[1][0|1|2]) ([0][1-9]|[1|2][0-9]|[3][0|1]) [0-9]{3} ([0-9]|[x])$/
//解释说明:[1-9][0-9]{5}----前6位;([1][9][0-9]{2}|[2][0][0|1][0-9]|[2][0][2][0-3])---7-10位,其中78位为19和20、202X的分别情况;([0][1-9]|[1][0|1|2]) ----11-12位;([0][1-9]|[1|2][0-9]|[3][0|1])----13-14位; [0-9]{3}---15-17位;([0-9]|[x])---18位
//判断格式是否正确
let format = idcard_patter.test(idcode);
//返回验证结果:校验码和格式同时正确才算是合法的身份证号码
return last === last_no && format;
}
总结
学海无涯,共同进步~