今天来说说身份证验证规则到底是怎么验证的,原理是什么,希望看完本篇你能正确的去理解身份证验证背后的规则。
身份证号码的编码规则
身份证号码共18位,由17位本体码和1位校验码组成。
身份证最后一位是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。作为尾号的校验码,是由号码编制单位按统一的公式计算出来的,如果某人的尾号是0-9,都不会出现X,但如果尾号是10,那么就得用X来代替,因为如果用10做尾号,那么此人的身份证就变成了19位,而19位的号码违反了国家标准,并且我国的计算机应用系统也不承认19位的身份证号码。Ⅹ是罗马数字的10,用X来代替10,可以保证公民的身份证符合国家标准。
- 前6位是地址码,表示登记户口时所在地的行政区划代码,依照《中华人民共和国行政区划代码》国家标准(GB/T2260)的规定执行;
- 7到14位是出生年月日,采用YYYYMMDD格式;
- 15到17位是顺序码,表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编订的顺序号,顺序码的奇数分配给男性,偶数分配给女性,即第17位奇数表示男性, 偶数表示女性;
第18位是校验码,采用ISO 7064:1983, MOD 11-2校验字符系统,计算规则下一章节说明。
一代身份证与二代身份证的区别在于:
- 一代身份证是15位,二代身份证是18位;
- 一代身份证出生年月日采用YYMMDD格式,二代身份证出生年月日采用YYYYMMDD格式;
- 一代身份证无校验码,二代身份证有校验码。
校验码计算规则
身份证号码中各个位置上的号码字符值应满足下列公式的校验:
下面通过两种方法用某个真实的男性身份证号(5 3 3 2 2 3 1 9 6 3 0 1 0 5 0 9 1 7)
来进行通俗易懂的说明身份证验证规则。
方法一(余数对应法)
- 将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2;
- 将这17位数字和系数相乘的结果相加;
- 用加出来的和除以11,看余数是多少;
- 余数只可能有0 1 2 3 4 5 6 7 8 9 10这11个数字。其分别对应的最后一位身份证的号码为1 0 X 9 8 7 6 5 4 3 2;
- 首先:我们计算5 X 7 + 3 X 3 + 3 X 10+2 X 5+…+1 X 2,前17位的乘积和是258
- 然后:用258除以11得出余数是5
- 最后:通过对应规则就可以知道余数5对应的数字是7。所以,这是一个合格的身份证号码。
方法二(十八位加权余一法)
按照18位来计算,第一位数的权重是07,第二位是09(见下表)序号从右向左,只要最后的加权和除以11,余数只要是1,那么身份证号码就是正确的。
注意
:如果身份证号码第18位是X,那么就按10计算。
其中5 X 7=35,3 X 9=27,3 X 10=30,其余以此类推,
加权求和=35+27+30…..2+7=265;265 % 11其余数是1,所以这个号码是正确的。
用JS实现二代身份证的验证
理解了原理和校验规则开始下手敲起来:
<script type="text/javascript">
/**
* 以下身份证验证适用于18位的二代身份证号码,身份证通常是由17位本体码和1位校验码组成。
**/
function validateIdCard(idCard) {
//15位和18位身份证号码的正则表达式
var regIdCard = /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/;
//如果通过该验证,说明身份证格式正确,但准确性还需计算
if (regIdCard.test(idCard)) {
if (idCard.length == 18) {
var idCardWi = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2); //将前17位加权因子保存在数组里
var idCardY = new Array(1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2); //这是除以11后,可能产生的11位余数、验证码,也保存成数组,10代表X
var idCardWiSum = 0; //用来保存前17位各自乖以加权因子后的总和
for (var i = 0; i < 17; i++) {
idCardWiSum += idCard.substring(i, i + 1) * idCardWi[i];
}
var idCardMod = idCardWiSum % 11;//计算出校验码所在数组的位置
var idCardLast = idCard.substring(17);//得到最后一位身份证号码
//如果等于2,则说明校验码是10,身份证号码最后一位应该是X
if (idCardMod == 2) {
if (idCardLast == "X" || idCardLast == "x") {
return "身份证号码验证通过!";
} else {
return "您输入的身份证号码有误!";
}
} else {
//用计算出的验证码与最后一位身份证号码匹配,如果一致,说明通过,否则是无效的身份证号码
if (idCardLast == idCardY[idCardMod]) {
return "身份证号码验证通过!";
} else {
return "您输入的身份证号码有误!";
}
}
}
} else {
return "您输入的身份证格式不正确!";
}
}
var inputs =validateIdCard(prompt());
var ids = document.getElementById("ids").innerHTML=inputs;
</script>
参考资料
- 中华人民共和国居民身份证法
- 中华人民共和国国家标准 GB/T 2260-2007 中华人民共和国行政区划代码
- 中华人民共和国国家标准 GB 11643-1999 公民身份证号码
- 中华人民共和国国家标准 GB/T 17710-1999 数据处理 校验码系统
- 中华人民共和国国家标准 GB/T 17710-2008 信息技术 安全技术 校验字符系统
- ISO 7064:1983 Data processing - Check character systems