1. package com.chauvet.utils;
  2.  
  3. import java.text.ParseException;
  4. import java.text.SimpleDateFormat;
  5. import java.util.Calendar;
  6. import java.util.Date;
  7. import java.util.GregorianCalendar;
  8. import java.util.HashMap;
  9. import java.util.Map;
  10. import java.util.regex.Matcher;
  11. import java.util.regex.Pattern;
  12.  
  13. /***
  14. *
  15. * 身份证18位分别代表的含义,身份证15位升级到18位,原来年用2位且没有最后一位,从左到右方分别表示
  16. * ①1-2 升级行政区代码
  17. * ②3-4 地级行政区划分代码
  18. * ③5-6 县区行政区分代码
  19. * ④7-10 11-12 13-14 出生年、月、日
  20. * ⑤15-17 顺序码,同一地区同年、同月、同日出生人的编号,奇数是男性,偶数是女性
  21. * ⑥18 校验码,如果是0-9则用0-9表示,如果是10则用X(罗马数字10)表示(最后一位可能出现的X并不是英文字母X,而是希腊数字10的缩写X)
  22. *
  23. * 只要将每位的对应权重乘以每个位上的数值,然后求和,最后与11求余数,得到的结果对比找到尾数即可。
  24. *
  25. * 原有15位身份证是没有校验位的,同时采用的是2位数字来表示出生年份
  26. *
  27. *
  28. *
  29. * 第一步:
  30. * 先对前17位数字的权求和 ,使用十七位数字本体码加权求和公式 S = Sum(Ai * Wi), i = 0, ... , 16
  31. * Ai:表示第i位置上的身份证号码数字值(0~9)
  32. * Wi:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 (固定的,表示第i位置上的加权因子)
  33. * 将身份证号码的第1位数字与7相乘;
  34. * 将身份证号码的第2位数字与9相乘;
  35. * 将身份证号码的第3位数字与10相乘;
  36. * 将身份证号码的第4位数字与5相乘;
  37. * 将身份证号码的第5位数字与8相乘;
  38. * 将身份证号码的第6位数字与4相乘;
  39. * 将身份证号码的第7位数字与2相乘;
  40. * 将身份证号码的第8位数字与1相乘;
  41. * 将身份证号码的第9位数字与6相乘;
  42. * 将身份证号码的第10位数字与3相乘;
  43. * 将身份证号码的第11位数字与7相乘;
  44. * 将身份证号码的第12位数字与9相乘;
  45. * 将身份证号码的第13位数字与10相乘;
  46. * 将身份证号码的第14位数字与5相乘;
  47. * 将身份证号码的第15位数字与8相乘;
  48. * 将身份证号码的第16位数字与4相乘;
  49. * 将身份证号码的第17位数字与2相乘。
  50. *
  51. * 第二步:
  52. * 将第一步身份证号码1~17位相乘的结果求和,全部加起来。
  53. *
  54. * 第三步:
  55. * 计算模 Y = mod(S, 11)
  56. * 用第二步计算出来的结果除以11,这样就会出现
  57. * 余数为0,
  58. * 余数为1,
  59. * 余数为2,
  60. * 余数为3,
  61. * 余数为4,
  62. * 余数为5,
  63. * 余数为6,
  64. * 余数为7,
  65. * 余数为8,
  66. * 余数为9,
  67. * 余数为10
  68. * 共11种可能性。
  69. *
  70. * 第四步:
  71. * 根据模,查找得到对应的校验码
  72. * Y: 0 1 2 3 4 5 6 7 8 9 10
  73. * 校验码: 1 0 X 9 8 7 6 5 4 3 2
  74. * 如果余数为0,那对应的最后一位身份证的号码为1;
  75. * 如果余数为1,那对应的最后一位身份证的号码为0;
  76. * 如果余数为2,那对应的最后一位身份证的号码为X;
  77. * 如果余数为3,那对应的最后一位身份证的号码为9;
  78. * 如果余数为4,那对应的最后一位身份证的号码为8;
  79. * 如果余数为5,那对应的最后一位身份证的号码为7;
  80. * 如果余数为6,那对应的最后一位身份证的号码为6;
  81. * 如果余数为7,那对应的最后一位身份证的号码为5;
  82. * 如果余数为8,那对应的最后一位身份证的号码为4;
  83. * 如果余数为9,那对应的最后一位身份证的号码为3;
  84. * 如果余数为10,那对应的最后一位身份证的号码为2。
  85. *
  86. * @author WXW
  87. *
  88. */
  89. public class IDValidate {
  90.  
  91. static String[] Wi = { "7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7","9", "10", "5", "8", "4", "2" };//十七位数字本体码权重
  92.  
  93. static String[] ValCodeArr = { "1", "0", "x", "9", "8", "7", "6", "5", "4","3", "2" }; //最后一位的校验码字符值
  94.  
  95. public static void main(String[] args) {
  96.  
  97. check("41272519910506****");
  98.  
  99. }
  100.  
  101. /***
  102. * 验证身份证
  103. * @param idStr
  104. * @return
  105. */
  106. public static boolean check(String idStr){
  107. try {
  108. if(null == idStr){// 验证非空
  109. System.out.println("身份证号码不能为空");
  110. return false;
  111. }
  112. if(idStr.length() != 15 && idStr.length() != 18){// 只能是15位或者18位
  113. System.out.println("身份证号码长度只能是15位或者18位");
  114. return false;
  115. }
  116.  
  117. String Ai = "";
  118. if (idStr.length() == 18) {
  119. Ai = idStr.substring(0, 17);
  120. }
  121.  
  122. if (idStr.length() == 15) {// 将15位身份证转换为 17位身份证,最后加上最后一位,转换为18位身份证
  123. // 15位身份证是没有校验位的,同时采用的是2位数字来表示出生年份,并且 15位的身份证号码确定都是19**年的
  124. Ai = idStr.substring(0, 6) + "19" + idStr.substring(6, 15);
  125. }
  126. if(!isNumber(Ai)){ // 验证身份证前17位是否都是数字
  127. System.out.println("身份证15位号码都应为数字 ; 18位号码除最后一位外,都应为数字。");
  128. return false;
  129. }
  130.  
  131. int year = Integer.parseInt(Ai.substring(6, 10));// 出生年份
  132. int month = Integer.parseInt(Ai.substring(10, 12));// 出生月份
  133. int day = Integer.parseInt(Ai.substring(12, 14));// 出生日期
  134. String birthDay = year+"-"+month+"-"+day;
  135.  
  136. Date birthdate = null;
  137. try {// 将出生日期转换为Date类型
  138. birthdate = new SimpleDateFormat("yyyyMMdd").parse(birthDay);
  139. } catch (ParseException e) {
  140. e.printStackTrace();
  141. System.out.println("身份证生日无效。");
  142. return false;
  143. }
  144. if (birthdate == null || new Date().before(birthdate)) {
  145. System.out.println("身份证生日无效。");
  146. return false;
  147. }
  148.  
  149. GregorianCalendar gc = new GregorianCalendar();//GregorianCalendar 是 Calendar 的一个具体子类,提供了世界上大多数国家/地区使用的标准日历系统。
  150. SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");
  151. // 验证生日年份是否在范围之内
  152. if ((gc.get(Calendar.YEAR) - year) > 150 || (gc.getTime().getTime() - s.parse(birthDay).getTime()) < 0) {
  153. System.out.println("身份证生日不在有效范围。");
  154. return false;
  155. }
  156.  
  157. //验证月份
  158. if (month > 12 || month <= 0) {
  159. System.out.println("身份证号中的月份无效");
  160. return false;
  161. }
  162.  
  163. //验证日期
  164. gc.setTime(birthdate);
  165. boolean mflag = false;
  166. switch (month) {
  167. case 1:
  168. case 3:
  169. case 5:
  170. case 7:
  171. case 8:
  172. case 10:
  173. case 12:
  174. mflag = (day >= 1 && day <= 31);
  175. break;
  176. case 2: // 公历的2月非闰年有28天,闰年的2月是29天。
  177. if (gc.isLeapYear(gc.get(Calendar.YEAR))) {
  178. mflag = (day >= 1 && day <= 29);
  179. } else {
  180. mflag = (day >= 1 && day <= 28);
  181. }
  182. break;
  183. case 4:
  184. case 6:
  185. case 9:
  186. case 11:
  187. mflag = (day >= 1 && day <= 30);
  188. break;
  189. }
  190. if (!mflag) {// 日期不对
  191. System.out.println("省份证号中的出生日期不对");
  192. return false;
  193. }
  194. // 验证 开头两位数是否是真实有效的地区编码
  195. if (cityCodeMap.get(Ai.substring(0, 2)) == null) {
  196. System.out.println("身份证地区编码错误。");
  197. return false;
  198. }
  199.  
  200. int TotalmulAiWi = 0;
  201. for (int i = 0; i < 17; i++) {//先对前17位数字的权求和 ,使用十七位数字本体码加权求和公式 S = Sum(Ai * Wi)
  202. TotalmulAiWi = TotalmulAiWi + Integer.parseInt(String.valueOf(Ai.charAt(i))) * Integer.parseInt(Wi[i]);
  203. }
  204. int modValue = TotalmulAiWi % 11;//计算模 Y = mod(S, 11) 用计算出来的结果除以11,这样就会出现
  205. String strVerifyCode = ValCodeArr[modValue]; // 获取最后一位的校验码字符值
  206. Ai = Ai + strVerifyCode; // 17位身份证 加上最后以为验证数字 得到18位有效的身份证号
  207.  
  208. if(!idStr.toUpperCase().equals(Ai.toUpperCase())){// 判断传过来的身份证号 和 计算得到的身份证号是否相同
  209. System.out.println("身份证号码不对");
  210. return false;
  211. }
  212. System.out.println("正确");
  213. return true;
  214. } catch (Exception e) {
  215. System.out.println("验证出错");
  216. e.printStackTrace();
  217. return false;
  218. }
  219.  
  220. }
  221.  
  222. /***
  223. * 地区编码
  224. */
  225. private static Map<String, String> cityCodeMap = new HashMap<String, String>() {
  226. {
  227. this.put("11", "北京");
  228. this.put("12", "天津");
  229. this.put("13", "河北");
  230. this.put("14", "山西");
  231. this.put("15", "内蒙古");
  232. this.put("21", "辽宁");
  233. this.put("22", "吉林");
  234. this.put("23", "黑龙江");
  235. this.put("31", "上海");
  236. this.put("32", "江苏");
  237. this.put("33", "浙江");
  238. this.put("34", "安徽");
  239. this.put("35", "福建");
  240. this.put("36", "江西");
  241. this.put("37", "山东");
  242. this.put("41", "河南");
  243. this.put("42", "湖北");
  244. this.put("43", "湖南");
  245. this.put("44", "广东");
  246. this.put("45", "广西");
  247. this.put("46", "海南");
  248. this.put("50", "重庆");
  249. this.put("51", "四川");
  250. this.put("52", "贵州");
  251. this.put("53", "云南");
  252. this.put("54", "西藏");
  253. this.put("61", "陕西");
  254. this.put("62", "甘肃");
  255. this.put("63", "青海");
  256. this.put("64", "宁夏");
  257. this.put("65", "新疆");
  258. this.put("71", "台湾");
  259. this.put("81", "香港");
  260. this.put("82", "澳门");
  261. this.put("91", "国外");
  262. }
  263. };
  264.  
  265. /***
  266. * 判断str是否为纯数字组成
  267. * @param str
  268. * @return
  269. */
  270. private static boolean isNumber(String str) {
  271. Pattern pattern = Pattern.compile("[0-9]*");
  272. Matcher isNum = pattern.matcher(str);
  273. return isNum.matches();
  274. }
  275. }

JAVA验证身份证号码是否合法的更多相关文章

  1. JAVA验证身份证号码是否正确

    package com.IdCard; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.D ...

  2. java验证身份证号码是否有效源代码 wn25的头像 wn25 23 2015-01-04 20:09 6 基本信息 Java × 1 浏览

    原文:http://www.open-open.com/code/view/1420373343171 1.描述 用java语言判断身份证号码是否有效,地区码.出身年月.校验码等验证算法 2.源代码 ...

  3. java验证身份证号码是否有效源代码

    原文:http://www.open-open.com/code/view/1420373343171 1.描述 用java语言判断身份证号码是否有效,地区码.出身年月.校验码等验证算法 2.源代码 ...

  4. 如何用javascript正则表达式验证身份证号码是否合法

    在用户注册页面有些需求要求的比较严格,需要对身份证js验证是否合法,通过此功能严格此系统软件,从而过滤到很多水客.下面就此实现方法给大家讲解下. 很多时候我们都是通过一组正则表达式来判断用户输入的身份 ...

  5. JAVA通过身份证号码获取出生日期、年龄、性别

    JAVA验证身份证号码是否正确:https://www.cnblogs.com/pxblog/p/12038278.html /** * 通过身份证号码获取出生日期(birthday).年龄(age) ...

  6. 具体验证身份证号码规则和姓名(汉字)的java代码

    一.验证汉字的正則表達式  /** 是否是汉字的正则 */  private String regexIsHanZi = "[\\u4e00-\\u9fa5]+";   * @pa ...

  7. php验证身份证号码的正确性

    /********************php验证身份证号码是否正确函数*********************/function is_idcard( $id ) {   $id = strto ...

  8. C#验证身份证号码

    一.18位的身份证号码 如:130429####%%%%00781.1~6位为地区代码,其中1.2位数为各省级政府的代码,3.4位数为地.市级政府的代码,5.6位数为县.区级政府代码.如13(河北省) ...

  9. php验证身份证号码正确性

    发布:JB01   来源:脚本学堂     [大 中 小] 分享一例php代码,用于验证身份证号码的正确性,用到了preg_match.preg_replace函数,有需要的朋友可以参考学习下.本文转 ...

随机推荐

  1. Maven 三种archetype说明

    新建Maven project项目时,需要选择archetype. 那么,什么是archetype? archetype的意思就是模板原型的意思,原型是一个Maven项目模板工具包.一个原型被定义为从 ...

  2. hdu3544找规律

    如果x>1&&y>1,可以简化到其中一个为1的情况,这是等价的,当其中一个为1(假设为x),另一个一定能执行y-1次, 这是一个贪心问题,把所有的执行次数加起来比较就能得到 ...

  3. 搞懂分布式技术11:分布式session解决方案与一致性hash

    搞懂分布式技术11:分布式session解决方案与一致性hash session一致性架构设计实践 原创: 58沈剑 架构师之路 2017-05-18 一.缘起 什么是session? 服务器为每个用 ...

  4. 变更Linux下的Java版本 alternatives

    默认正常情况下,即使使用Java 1.6版本Java脚本jdk-6u31-linux-i586.bin,安装Java运行后,会出现自动升级为1.7版本状态的情况.针对某些应用程序需要基于1.6版本方可 ...

  5. 【Error】local variable 'xxx' referenced before assignment

    此种错误涉及到变量的作用域,即全局变量和局部变量的操作. 总结如下: 内部函数,不修改全局变量可以访问全局变量 内部函数,修改同名全局变量,则python会认为它是一个局部变量 在内部函数修改同名全局 ...

  6. vue-router防跳墙控制

    vue-router防跳墙控制 因为在实际开发中,从自己的角度来看,发现可以通过地址栏输入地址,便可以进入本没有权限的网页.而我们一般只是操作登录页面,其他页面很少考虑,此刻特来尝试解决一下 基于vu ...

  7. vuejs绑定img 的src

    1.显示本地图片: <img src="../../common/images/auth-icon.png" />   2.绑定变量: <img class=&q ...

  8. 019——VUE中v-for与computer结合功能实例讲解

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  9. js停止(阻止)浏览器继续加载内容

    这个应该是一个比较特殊的要求,一般网站都没有这个功能,对于一个新手来说,真的不知道从何处下手,只有在网上搜索了,寻找现成答案,寻寻觅觅一天没有结果.但是这个功能还是需要,第二天继续网上大肆搜寻.终于功 ...

  10. jstack 分析程序性能

    摘录自:https://www.jianshu.com/p/6690f7e92f27 简要说明下步骤: 1:通过top命令,cpu,占用率较高的进程 2:通过 top -Hp PID 查看该进程中线程 ...