中国居民身份证校验码算法
步骤如下:
- 将本体码(身份证号码)前面的17位数分别乘以对应的加权因子。
- 将这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,X实际是罗马数字10。
公民身份号码中各位置上对应的加权因子 | |||||||||||||||||
i | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
W | 7 | 9 | 10 | 5 | 8 | 4 | 2 | 1 | 6 | 3 | 7 | 9 | 10 | 5 | 8 | 4 | 2 |
余数对应的校验码 | |||||||||||
余数 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
校验码 | 1 | 0 | X | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 |
例:110101200001101035
求最后一位校验码过程如下:
身份证
|
1
|
1
|
0
|
1
|
0
|
1
|
2
|
0
|
0
|
0
|
0
|
1
|
1
|
0
|
1
|
0
|
3
|
加权因子
|
7
|
9
|
10
|
5
|
8
|
4
|
2
|
1
|
6
|
3
|
7
|
9
|
10
|
5
|
8
|
4
|
2
|
求和
|
(1*7)+(1*9)+(0*10)+(1*5)+(0*8)+(1*4)+(2*2)+(0*1)+(0*6)+(0*3)+(0*7)+(1*9)+(1*10)+(0*5)+(1*8)+(0*4)+(3*2)=62
|
||||||||||||||||
求余
|
62 % 11 = 7
|
||||||||||||||||
校验码
|
余数7对应的校验码为5
|
代码:
1 public static bool CheckIsIdCard(string Id) 2 { 3 long n = 0; 4 if (long.TryParse(Id.Remove(17), out n) == false || n < Math.Pow(10, 16) || long.TryParse(Id.Replace('x', '0').Replace('X', '0'), out n) == false) 5 { 6 return false; //数字验证 7 } 8 9 var address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91"; 10 if (address.IndexOf(Id.Remove(2), System.StringComparison.Ordinal) == -1) 11 { 12 return false; //省份验证 13 } 14 15 var birth = Id.Substring(6, 8).Insert(6, "-").Insert(4, "-"); 16 var time = new DateTime(); 17 if (DateTime.TryParse(birth, out time) == false) 18 { 19 return false; //生日验证 20 } 21 22 var arrVarifyCode = ("1,0,x,9,8,7,6,5,4,3,2").Split(','); //校验码 23 var Wi = ("7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2").Split(','); //加权因子 24 var Ai = Id.Remove(17).ToCharArray(); //返回除所删除的指定位置上的字符外的新字符串 25 26 var sum = 0; 27 for (var i = 0; i < 17; i++) 28 { 29 sum += int.Parse(Wi[i]) * int.Parse(Ai[i].ToString()); 30 } 31 32 var y = -1; 33 Math.DivRem(sum, 11, out y); //计算两个 32 位有符号整数的商,并通过输出参数返回余数 34 if (arrVarifyCode[y] != Id.Substring(17, 1).ToLower()) 35 { 36 return false; //校验码验证 37 } 38 return true; //符合GB11643-1999标准 39 }