参考资料 
1 java实现的18位身份证格式验证算法 
http://fanqiang.chinaunix.net/program/java/2006-06-22/4639.shtml  
原码中有少许错误,我已经调整过来了 
2 身份证效验规则,经典  
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身份证验证代码类 
http://download.csdn.net/source/2967003  
特别说明,第一个链接上的源码不是最新的,作者已经上传CSDN了 
见奉上ZeroLine的源码

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

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

Java代码  
  1. public class IDCard {
  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. // verify digit
  5. final int[] vi = { 1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2 };
  6. private int[] ai = new int[18];
  7. public IDCard() {
  8. }
  9. // verify
  10. public boolean Verify(String idcard) {
  11. if (idcard.length() == 15) {
  12. idcard = uptoeighteen(idcard);
  13. }
  14. if (idcard.length() != 18) {
  15. return false;
  16. }
  17. String verify = idcard.substring(17, 18);
  18. if (verify.equals(getVerify(idcard))) {
  19. return true;
  20. }
  21. return false;
  22. }
  23. // get verify
  24. public String getVerify(String eightcardid) {
  25. int remaining = 0;
  26. if (eightcardid.length() == 18) {
  27. eightcardid = eightcardid.substring(0, 17);
  28. }
  29. if (eightcardid.length() == 17) {
  30. int sum = 0;
  31. for (int i = 0; i < 17; i++) {
  32. String k = eightcardid.substring(i, i + 1);
  33. ai[i] = Integer.parseInt(k);
  34. }
  35. for (int i = 0; i < 17; i++) {
  36. sum = sum + wi[i] * ai[i];
  37. }
  38. remaining = sum % 11;
  39. }
  40. return remaining == 2 ? "X" : String.valueOf(vi[remaining]);
  41. }
  42. // 15 update to 18
  43. public String uptoeighteen(String fifteencardid) {
  44. String eightcardid = fifteencardid.substring(0, 6);
  45. eightcardid = eightcardid + "19";
  46. eightcardid = eightcardid + fifteencardid.substring(6, 15);
  47. eightcardid = eightcardid + getVerify(eightcardid);
  48. return eightcardid;
  49. }
  50. }

测试类

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

经典验证类:

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

相比第一个代码量更少!  推荐呀

经过改写后的javascript版本:

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

经过测试OK

身份证15位转换为18位,参考文章:15位身份证号码转18位的JSP程序 
http://www.java3z.com/cwbwebhome/article/article5a/5105.jsp?id=7  
Java版

Java代码  
  1. /**
  2. * 身份证15位转换18位
  3. * */
  4. public static String idCard15To18(String ID15) {
  5. String ID18 = "";
  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. String ID17 = ID15.substring(0, 6) + "19" + ID15.substring(6, 15);
  13. int[] ID17Array;
  14. ID17Array = new int[17];
  15. for (int i = 0; i < 17; i++) {
  16. ID17Array[i] = Integer.parseInt(ID17.substring(i, i + 1));
  17. }
  18. int s = 0;
  19. for (int i = 0; i < 17; i++) {
  20. s = s + ID17Array[i] * w[i];
  21. }
  22. s = s % 11;
  23. ID18 = ID17 + Character.toString(A[s]);
  24. }
  25. return ID18;
  26. }

JavaScrpt版本

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

验证15,18身份证号码的合法性 
参考资料 
1 js 验证 15位 、 18位 身份证 
http://yanpinquan.blog.163.com/blog/static/281162892011510105435903/  
2 用javascript验证身份证号码15位或18位 
http://topic.csdn.net/t/20050923/10/4288822.html

Java代码  
  1. function   checkIDCard (str)
  2. {   //身份证正则表达式(15位)
  3. isIDCard1=/^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$/;
  4. //身份证正则表达式(18位)
  5. isIDCard2=/^[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   (isIDCard1.test(str)||isIDCard2.test(str));
  8. }

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

java,javascript对18位身份证格式的验证算法相关推荐

  1. java字符串应用之18位身份证格式验证

    公民身份号码是特征组合码,由17位数字本体码和1位数字校验码组成.排列顺序从左至右依次为:6位数字地址码.8位数字出生日期码,3位数字顺序码和1位数字校验码.     地址码:表示编码对象常住户口所在 ...

  2. java中验证18位身份证的正则表达式

    import java.util.regex.Matcher; import java.util.regex.Pattern; /** *只可以验证输入的身份证是否为18位,不可以验证身份证的正确性 ...

  3. .Net验证18位身份证格式

    /// <summary>/// 验证18位号码/// </summary>/// <param name="Id"></param> ...

  4. 15位或18位身份证验证

    c#实现的18位身份证格式验证算法 18位身份证标准在国家质量技术监督局于1999年7月1日实施的GB11643-1999<公民身份号码>中做了明确的规定. GB11643-1999< ...

  5. 关于18位身份证号码最后一位计算(Java实现)

    关于18位身份证号码最后一位计算(Java实现) 现代的身份证号码长度都是18位的,但是只要知道前17位便可推出第18位数字或者字母(第18位为0,1,...,9和X中的一个).也就是说,国内不存在前 ...

  6. java代码实现15位身份证号码升级到18位

    转载网址   点击打开链接 转载一份作为记录,真心不错.受教! 18位身份证号码的组成: 公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成.排列顺序从左至右依次为:六位数字地址码,八位数字 ...

  7. javascript 15位和18位身份证的正则表达式及其验证

    1.简单的正则表达式: (1)preg_match("/^(\d{18,18}|\d{15,15}|\d{17,17}x)$/",$id_card) (2)preg_match(& ...

  8. 15/18位身份证号码验证

    15/18位身份证号码验证 在做身份证验证之前你得明确身份证号的组成. 首先我告诉你,18位身份证号码后面的字母只有"X"这一个.(X是罗马数字的10,用X来代替10,可以保证您的 ...

  9. excel表格中18位身份证号码如何转换成出生日期

    1.获取出生日期,如果Excel表上,如果A1为身份证号码. =IF(LEN(A1)=15,MID(A1,7,2)&"-"&MID(A1,9,2)&&quo ...

最新文章

  1. 【Python基础】用Python制作漂亮的流动桑基图
  2. HDU - 6602 Longest Subarray(线段树+思维)
  3. ABP vNext微服务架构详细教程——身份管理服务
  4. [转载] python与c/c++相比有哪些优势
  5. 如何平衡存储系统的一致性和可用性?
  6. 【Python】下载所有 XKCD 漫画
  7. Eclipse添加JBOSS支持
  8. mysql查询语法错误_MySQL内部联接查询语法错误
  9. iOS 刘海屏 隐藏横条 home键
  10. 移动云招聘,加入我们,搞点大事~
  11. 奇妙的数字 小明发现了一个奇妙的数字。它的平方和立方正好把0~9的10个数字每个用且只用了一次。你能猜出这个数字是多少吗?
  12. MEMS传感器的下一轮技术变革
  13. 如何写论文的report(一)
  14. ue4 射线Trace Responses(踪迹响应)
  15. html+js+canvas实现画板涂画功能和vue+canvas实现画板涂画功能
  16. python制作英汉词典_Python基于有道实现英汉字典功能
  17. matlab恒定值,基于MATLAB的明渠恒定非均匀渐变流水面线的数值计算
  18. (直播、监控)利用javacv解析rtsp流,转换为flv流,通过前端flv.js解析播放
  19. JDK 14如期发布,16个新特性快速预览
  20. 手把手教你读财报----银行业----第四课

热门文章

  1. 【环信IM集成教程】iOS端收到离线消息显示设置
  2. RFID仓储管理系统解决方案实施可视化流程
  3. 专访实在智能CEO孙林君:聚焦AI+RPA赛道,为全社会贡献100万个数字员工
  4. 提取OutLook邮件里面的邮件头信息(发件人、收件人)
  5. 小米盒子4用u盘导入html文件格式,小米盒子4如何安装应用到U盘,一招彻底解决内存...
  6. 福昕PDF阅读器无法修改、注释文档,解决办法!
  7. Lenovo x3650m5 如何进入BIOS
  8. c语言实现pdf显示图片,C语言读取BMP格式图片.pdf
  9. 独孤思维:这个圣诞节,你在为谁赚钱?
  10. swift编写的项目源代码_通过在Swift中命名模型来编写简洁的代码