Frenlee

身份证号码的简单验证

概述

利用身份证号码的生成规则,简单的验证身份证号码的准确性.

验证原理

  • 将前面的身份证号码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。
  • 通过上面得知如果余数是3,就会在身份证的第18位数字上出现的是9。如果对应的数字是2,身份证的最后一位号码就是罗马数字x。

    例如:某男性的身份证号码为【53010219200508011x】, 我们看看这个身份证是不是合法的身份证。
    首先我们得出前17位的乘积和【(57)+(39)+(010)+(15)+(08)+(24)+(12)+(91)+(26)+(03)+(07)+(59)+(010)+(85)+(08)+(14)+(1*2)】是189,然后用189除以11得出的结果是189/11=17—-2,也就是说其余数是2。最后通过对应规则就可以知道余数2对应的检验码是X。所以,可以判定这是一个正确的身份证号码。

身份证的构成

身份证号分为两种,旧的为15位,新的为18位。身份证15位编码规则:dddddd yymmdd xx p 其中 dddddd:地区码 yymmdd: 出生年月日 xx: 顺序类编码,无法确定 p: 性别,奇数为男,偶数为女; 身份证18位编码规则:dddddd yyyymmdd xxx y 其中 dddddd:地区码 yyyymmdd: 出生年月日 xxx:顺序类编码,无法确定,奇数为男,偶数为女 y: 校验码,该位数值可通过前17位计算获得,计算的公式见程序,一些需要用到的常数:18位号码加权因子为(从右到左) Wi = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2,1 ] 验证位 Y = [ 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 ] 校验位计算公式:Y_P = mod( ∑(Ai×Wi),11 ) i为身份证号码从右往左数的 2…18 位; Y_P为脚丫校验码所在校验码数组位置。

验证实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
var Wi = [ 7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2,1];//加权因子
var ValideCode = [1,0,10,9,8,7,6,5,4,3,2];//身份证验证值 10代表X
//验证函数
function IdCardValidata(idCard){
idCard = trim(idCard.replace(/ /g, ""));//去掉字符串头尾空格
if(idCard.length == 15){
return isValidityBrithBy15IdCard(idCard);//进行15位身份证的验证
}else if(idCard.length == 18){
var a_idCard = idCard.split("");//得到身份证数组
if(isValidityBrithBy18IdCard(idCard) && isTrueValidateCodeBy18IdCard(a_idCard)){
return true;
}else{
return false;
}
}else{
return false;
}
}

/**
* 判断身份证号码为18位时最后的验证位是否正确
* @param a_idCard 身份证号码数组
* @return
*/
function isTrueValidateCodeBy18IdCard(a_idCard){
var sum = 0;//声明加权求和变量
if(a_idCard[17].toLowerCase() == 'x'){
a_idCard[17] = 10;//将最后位为x的验证码替换为10方便后续操作
}
for( var i = 0; i < 17 ; i++){
sum += Wi[i] * a_idCard[i];//求加权和
}
valCodePosition = sum % 11;//得到验证码所在位置
if(a_idCard[17] == ValideCode[valCodePosition]){
return true;
}else{
return false;
}
}

/**
* 验证18位数身份证号码中的生日是否有效
* @param idCard 18位身份证字符串
* @return
*/
function isValidityBrithBy18IdCard(idCard){
var year = idCard.substring(6,10);
var month = idCard.substring(10,12);
var day = idCard.substring(12,14);
var temp_date = new Date(year, parseFloat(month)-1, parseFloat(day));
//这里用getFullYear()获取年份,避免千年虫问题
if(temp_date.getFullYear() !=parseFloat(year) || temp_date.getMonth() != parseFloat(month)-1 || temp_date.getDate() != parseFloat(day)){
return false;
}else{
return true;
}
}

/**
* 验证15位数身份证好好的生日是否有效生日
* @param idCard 15位身份证字符串
*/
function isValidityBrithBy15IdCard(idCard){
var year = idCard.substring(6,8);
var month = idCard.substring(8,10);
var day = idCard.substring(10,12);
var temp_date = new Date(year,parseFloat(mont)-1, parseFloat(day));
//对于老身份证中你的年龄则不需考虑千年虫问题而使用getYear()方法
if(temp_date.getYear() != parseFloat(year) || temp_date.getMonth() != parseFloat(mont)-1 || temp_date.getDay != parseFloat(day)){
return false;
}else{
return true;
}
}

//去掉字符串头尾空格
function trim(str){
return str.replace(/(^\s*)|(\s*$)/g, "");
}