公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。
排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码,最后一位是数字校验码。
身份证最后一位是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。作为尾号的校验码,是由号码编制单位按统一的公式计算出来的,如果某人的尾号是0-9,都不会出现X,但如果尾号是10,那么就得用X来代替,因为如果用10做尾号,那么此人的身份证就变成了19位,而19位的号码违反了国家标准,并且我国的计算机系统也不承认19位的身份证号码。Ⅹ是罗马数字的10,用X来代替10,可以保证公民的身份证符合国家标准。
计算方法
1、将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 ;
2、将这17位数字和系数相乘的结果相加;
3、用加出来和除以11,看余数是多少;
4、余数只可能有0 1 2 3 4 5 6 7 8 9 10这11个数字。其分别对应的最后一位身份证的号码为1 0 X 9 8 7 6 5 4 3 2;
5、通过上面得知如果余数是2,就会在身份证的第18位数字上出现罗马数字的X。如果余数是10,身份证的最后一位号码就是2;
例如:某男性的身份证号码是34052419800101001X。我们要看看这个身份证是不是合法的身份证。
首先:我们计算3*7+4*9+0*10+5*5+...+1*2,前17位的乘积和是189
然后:用189除以11得出的结果是商17余2
最后:通过对应规则就可以知道余数2对应的数字是x。所以,这是一个合格的身份证号码。
1 // 验证身份证号,成功则返回省份编号+出生日期+性别
2 function identifyCard(sId){
3 // 省份编号
4 var aCity={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:"国外 "};
5
6 //判断身份证号是否18位
7 if(!/^\d{17}(\d|x)$/i.test(sId))
8 return -1;
9
10 //将身份证号的x替换成a
11 sId=sId.replace(/x$/i,"a");
12
13 //判断地区编号是否合法
14 if(aCity[parseInt(sId.substr(0,2))]==null)
15 return -2; //return "Error:非法地区";
16
17 //判断出生日期是否合法
18 var sBirthday=sId.substr(6,4)+"-"+Number(sId.substr(10,2))+"-"+Number(sId.substr(12,2)); //如:1986-07-15
19 var d=new Date(sBirthday.replace(/-/g,"/")); //如:1986/07/15
20 if(sBirthday!=(d.getFullYear()+"-"+ (d.getMonth()+1) + "-" + d.getDate()))
21 return -3;//return "Error:非法生日";
22
23 //判断最后一位校验码是否正确
24 //身份证号的后四位的前三位是当日出生的顺序码,奇为男,偶为女;
25 //最后一位是校验码,由前17位数字乘以指定系数的结果相加,然后除以11,得到余数,这余数对应[1 0 X 9 8 7 6 5 4 3 2]中的数字。如余数是1,那么最终的校验码就是0;余数是2,最终校验码就是X
26 var iSum = 0;
27 for(var i = 17;i>=0;i --)
28 iSum += (Math.pow(2,i) % 11) * parseInt(sId.charAt(17 - i),11);
29 if(iSum%11!=1)
30 return -4; //return "Error:非法证号";
31 birthday = ""+sId.substr(6,4)+Number(sId.substr(10,2))+Number(sId.substr(12,2));
32 return ""+parseInt(sId.substr(0,2))+birthday+(sId.substr(16,1)%2?1:2); //"男":"女");
33 }