参考资料 


1 java实现的18位身份证格式验证算法 


​http://fanqiang.chinaunix.net/program/java/2006-06-22/4639.shtml​

 


原码中有少许错误,我已经调整过来了

java,javascript对18位身份证格式的验证算法_java代码

 


2 身份证效验规则,经典

java,javascript对18位身份证格式的验证算法_java代码

 


​http://since2006.com/blog/176​

 


公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成.排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。 


1、地址码 


表示编码对象常住户口所在县(市、旗、区)的行政区划代码,按 GB/T 2260 的规定执行。 


2、出生日期码 


表示编码对象出生的年、月、日,按 GB/T 7408 的规定执行。年、月、日代码之间不用分隔符。例:某人出生日期为 1966年10月26日,其出生日期码为 19661026。 


3、顺序码 


表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数千分配给女性。 


4 、校验码 


根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。由(1,2,3,4,5,6,7,8,9,X)构成. 


(1)十七位数字本体码加权求和公式 


  S = Sum(Ai * Wi), i = 0, ... , 16 ,先对前17位数字的权求和 


  Ai:表示第i位置上的身份证号码数字值 


  Wi:表示第i位置上的加权因子 


  Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 


(2)计算模 


  Y = mod(S, 11) 


(3)通过模得到对应的校验码 


    Y:   0 1 2 3 4 5 6 7 8 9 10 


    校验码: 1 0 X 9 8 7 6 5 4 3 2 


下面举例说明该计算方法并用代码实现。 

公式:Ax=(∑(Ai×Wi))(mod 11)…………………………(1) 

i----表示身份证号码字符从右至左包括校验码在内的位置序号; 

Ai----表示第i位置上的数字号码; 

Ax----数字校验码的值; 

Wi----示第i位置上的加权因子; 

公式:Wi=(2^(i-1))(mod 11)…………………………(2) 

设某男性公民身份号码为51310119820113001,首先得到各个变量: 

    i  18  17  16  15  14  13  12  11  10   9   8   7   6   5   4   3   2   1 

由公式(2)可得: 

    Wi  7   9  10   5   8   4   2   1   6   3   7   9  10   5   8   4   2   1 

------------------------------------------------------------------------------- 

    Ai  5   1   3   1   0   1   1   9   8   2   0   1   1   3   0   0   1  Ax 

Ai×Wi 35   9  30   5   0   4   2   9  48   6   0   9  10  15   0   0   2  A1 

按照公式(1)计算: 

∑(Ai×Wi)=(35+9+30+5+0+4+2+9+48+6+0+9+10+15+0+0+2)=184 

184÷11=16+8/11 

∑(Ai×Wi)(mod 11)=8 

然后根据计算的结果,从下表中查出相应的校验码,X表示结果为10: 

∑(Ai×WI)(mod 11) 0 1 2 3 4 5 6 7 8 9 10 

校验码字符值Ai     1 0 X 9 8 7 6 5 4 3 2 

根据上面的方法,查出计算结果为8的校验码为4所以该人员的公民身份号码应该为513101198201130014

 


最新调整及修改:

 


参考资料 


1 JAVA代码验证身份证信息 


​http://www.blogjava.net/zeroline/archive/2011/01/03/342227.html​

 


2 java身份证验证代码类 



 


特别说明,第一个链接上的源码不是最新的,作者已经上传CSDN了 

见奉上ZeroLine的源码

 

java,javascript对18位身份证格式的验证算法_java代码_03


1. import
2. import
3. import
4. import
5.
6. /**
7. * 身份证验证的工具(支持5位或18位省份证)<br/>
8. * 身份证号码结构:
9. * <ol>
10. * <li>17位数字和1位校验码:6位地址码数字,8位生日数字,3位出生时间顺序号,1位校验码。</li>
11. * <li>地址码(前6位):表示对象常住户口所在县(市、镇、区)的行政区划代码,按GB/T2260的规定执行。</li>
12. * <li>出生日期码,(第七位 至十四位):表示编码对象出生年、月、日,按GB按GB/T7408的规定执行,年、月、日代码之间不用分隔符。</li>
13. * <li>顺序码(第十五位至十七位):表示在同一地址码所标示的区域范围内,对同年、同月、同日出生的人编订的顺序号,
14. * 顺序码的奇数分配给男性,偶数分配给女性。</li>
15. * <li>校验码(第十八位数):<br/>
16. * <ul>
17. * <li>十七位数字本体码加权求和公式 s = sum(Ai*Wi), i = 0,,16,先对前17位数字的权求和;
18. * Ai:表示第i位置上的身份证号码数字值.Wi:表示第i位置上的加权因.Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2;</li>
19. *<li>计算模 Y = mod(S, 11)</li>
20. *<li>通过模得到对应的校验码 Y: 0 1 2 3 4 5 6 7 8 9 10 校验码: 1 0 X 9 8 7 6 5 4 3 2</li>
21. *</ul>
22. *</li>
23. *</ol>
24. *
25. *@author cxy
26. *@since 2011-1-7
27. *@see {@link http://www.blogjava.net/zeroline/archive/2011/01/03/342227.html}
28. */
29. public class
30. final static Map<Integer, String> zoneNum = new
31. static
32. 11, "北京");
33. 12, "天津");
34. 13, "河北");
35. 14, "山西");
36. 15, "内蒙古");
37. 21, "辽宁");
38. 22, "吉林");
39. 23, "黑龙江");
40. 31, "上海");
41. 32, "江苏");
42. 33, "浙江");
43. 34, "安徽");
44. 35, "福建");
45. 36, "江西");
46. 37, "山东");
47. 41, "河南");
48. 42, "湖北");
49. 43, "湖南");
50. 44, "广东");
51. 45, "广西");
52. 46, "海南");
53. 50, "重庆");
54. 51, "四川");
55. 52, "贵州");
56. 53, "云南");
57. 54, "西藏");
58. 61, "陕西");
59. 62, "甘肃");
60. 63, "青海");
61. 64, "新疆");
62. 71, "台湾");
63. 81, "香港");
64. 82, "澳门");
65. 91, "外国");
66. }
67.
68. final static int[] PARITYBIT = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
69. final static int[] POWER_LIST = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10,
70. 5, 8, 4, 2};
71.
72. /**
73. *
74. * 身份证验证
75. *
76. *@param s
77. * 号码内容
78. *@return 是否有效 null和"" 都是false
79. */
80. public static boolean
81. if(s == null || (s.length() != 15 && s.length() != 18))
82. return false;
83. final char[] cs = s.toUpperCase().toCharArray();
84. //校验位数
85. int power = 0;
86. for(int i=0; i<cs.length; i++){
87. if(i==cs.length-1 && cs[i] == 'X')
88. break;//最后一位可以 是X或x
89. if(cs[i]<'0' || cs[i]>'9')
90. return false;
91. if(i < cs.length -1){
92. '0') * POWER_LIST[i];
93. }
94. }
95.
96. //校验区位码
97. if(!zoneNum.containsKey(Integer.valueOf(s.substring(0,2)))){
98. return false;
99. }
100.
101. //校验年份
102. 15 ? getIdcardCalendar() + s.substring(6,8) :s.substring(6, 10);
103.
104. final int
105. if(iyear < 1900
106. return false;//1900年的PASS,超过今年的PASS
107.
108. //校验月份
109. 15 ? s.substring(8, 10) : s.substring(10,12);
110. final int
111. if(imonth <1 || imonth >12){
112. return false;
113. }
114.
115. //校验天数
116. 15 ? s.substring(10, 12) : s.substring(12, 14);
117. final int
118. if(iday < 1 || iday > 31)
119. return false;
120.
121. //校验一个合法的年月日:已经得到校验了
122. /*if(!validate(iyear, imonth, iday))
123. return false;*/
124.
125. //校验"校验码"
126. if(s.length() == 15)
127. return true;
128. return cs[cs.length -1 ] == PARITYBIT[power % 11];
129. }
130.
131. private static int
132. new
133. int
134. int year2bit = Integer.parseInt(String.valueOf(curYear).substring(2));
135. return
136. }
137.
138. @Deprecated
139. static boolean validate(int year, int imonth, int
140. //比如考虑闰月,大小月等
141. return true;
142. }
143.
144. public static void
145.
146. "124578457845784571","124578200402284571","510521195402201748","510522200402306644"};
147. for(String sfz : idCard){
148. System.out.println(isIdcard(sfz));
149. }
150. }
151. }



经过测试以下身份证验证不准确,作个参考吧!如身份证号码:124578457845784571

 


经过调整后的源码: 


java,javascript对18位身份证格式的验证算法_java代码_03



    1. public class
    2. // wi =2(n-1)(mod 11)
    3. final int[] wi = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1
    4.
    5. // verify digit
    6. final int[] vi = { 1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2
    7.
    8. private int[] ai = new int[18];
    9.
    10. public
    11. }
    12.
    13. // verify
    14. public boolean
    15. if (idcard.length() == 15) {
    16. idcard = uptoeighteen(idcard);
    17. }
    18. if (idcard.length() != 18) {
    19. return false;
    20. }
    21. 17, 18);
    22. if
    23. return true;
    24. }
    25. return false;
    26. }
    27.
    28. // get verify
    29. public
    30. int remaining = 0;
    31.
    32. if (eightcardid.length() == 18) {
    33. 0, 17);
    34. }
    35.
    36. if (eightcardid.length() == 17) {
    37. int sum = 0;
    38. for (int i = 0; i < 17; i++) {
    39. 1);
    40. ai[i] = Integer.parseInt(k);
    41. }
    42.
    43. for (int i = 0; i < 17; i++) {
    44. sum = sum + wi[i] * ai[i];
    45. }
    46. 11;
    47. }
    48.
    49. return remaining == 2 ? "X"
    50. }
    51.
    52. // 15 update to 18
    53. public
    54. 0, 6);
    55. "19";
    56. 6, 15);
    57. eightcardid = eightcardid + getVerify(eightcardid);
    58. return
    59. }
    60. }

    测试类 


    java,javascript对18位身份证格式的验证算法_java代码_03



    1. IDCard idcard = new
    2. System.out.println(idcard.Verify(sfz));




    经典验证类: 


    java,javascript对18位身份证格式的验证算法_java代码_03


    1. public class
    2.
    3. public boolean
    4. int sigma = 0;
    5. 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2
    6. "1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"
    7. for (int i = 0; i < 17; i++) {
    8. int ai = Integer.parseInt(arrIdCard.substring(i, i + 1));
    9. int
    10. sigma += ai * wi;
    11. }
    12. int number = sigma % 11;
    13. String check_number = w[number];
    14. if (!arrIdCard.substring(17).equals(check_number)) {
    15. return false;
    16. else
    17. return true;
    18. }
    19. }
    20. }


    相比第一个代码量更少!

    java,javascript对18位身份证格式的验证算法_java_07

     推荐呀 



    经过改写后的javascript版本:

    java,javascript对18位身份证格式的验证算法_java代码

     


    java,javascript对18位身份证格式的验证算法_java代码_03


    1. function isIdCard(arrIdCard){
    2. false;
    3. 0;
    4. new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2
    5. new Array("1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2");
    6. for (var i = 0; i < 17; i++) {
    7. 1));
    8. var wi = a[i];
    9. sigma += ai * wi;
    10. }
    11. 11;
    12. var check_number = w[number];
    13. if (arrIdCard.substring(17) != check_number) {
    14. false;
    15. else
    16. true;
    17. }
    18. return
    19. }


    经过测试OK

    java,javascript对18位身份证格式的验证算法_校验码_10

     



    身份证15位转换为18位,参考文章:15位身份证号码转18位的JSP程序 


    ​http://www.java3z.com/cwbwebhome/article/article5a/5105.jsp?id=7​

     


    Java版 


    java,javascript对18位身份证格式的验证算法_java代码_03


    1. /**
    2. * 身份证15位转换18位
    3. * */
    4. public static
    5. "";
    6. if (ID15.length() == 18) {
    7. ID18 = ID15.toUpperCase();
    8. }
    9. if (ID15.length() == 15) {
    10. int[] w = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1
    11. char[] A = { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'
    12. 0, 6) + "19" + ID15.substring(6, 15);
    13. int[] ID17Array;
    14. new int[17];
    15. for (int i = 0; i < 17; i++) {
    16. 1));
    17. }
    18. int s = 0;
    19. for (int i = 0; i < 17; i++) {
    20. s = s + ID17Array[i] * w[i];
    21. }
    22. 11;
    23. ID18 = ID17 + Character.toString(A[s]);
    24. }
    25. return
    26. }


    JavaScrpt版本 


    java,javascript对18位身份证格式的验证算法_java代码_03


    1. function idCard15To18(id){
    2. new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1);
    3. new Array("1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2");
    4. 0;
    5. var newid;
    6. newid = id;
    7. 0,6)+"19"+newid.substring(6,id.length);
    8. for(i=0;i<newid.length;i++ ){
    9. 1))*W[i];
    10. s=s+j;
    11. }
    12. 11;
    13. newid=newid+A[s];
    14. return
    15. }



    验证15,18身份证号码的合法性 


    参考资料 


    1 js 验证 15位 、 18位 身份证 


    ​http://yanpinquan.blog.163.com/blog/static/281162892011510105435903/​

     


    2 用javascript验证身份证号码15位或18位 


     


    java,javascript对18位身份证格式的验证算法_java代码_03


    1. function   checkIDCard (str)
    2. { //身份证正则表达式(15位)
    3. 1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$/;
    4. //身份证正则表达式(18位)
    5. 1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{4}$/;
    6. //验证身份证,返回结果
    7. return
    8. }


    这个方法不是很正确,正确的做法是:先将15转换为18位,在调用方法验证是否正确

    !

    java,javascript对18位身份证格式的验证算法_java_07