【工具类】身份证号码相关验证

2019-12-19 05:51:13来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

【工具类】身份证号码相关验证

验证身份证真实性、根据身份证号码获取相关年龄、性别、生日、星座等信息。

直接上代码

  1 package com.itxs.util;
  2 
  3 import java.text.SimpleDateFormat;
  4 import java.util.Calendar;
  5 import java.util.Date;
  6 import java.util.HashMap;
  7 import java.util.Map;
  8 
  9 /**
 10  * description 身份证号码工具类 
 11  * @author 
12
* @2019年9月20日 13 */ 14 public class IdCardUtil { 15 16 //中国公民身份证号码最小长度 17 public static final int CHINA_ID_MIN_LENGTH = 15; 18 19 //中国公民身份证号码最大长度。 20 public static final int CHINA_ID_MAX_LENGTH = 18; 21 //每位加权因子 22 public static final int power[] = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 }; 23 24 private static final String pattern18 = "^[1-9][0-7]\\d{4}((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})(((0[13578]|1[02])(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)(0[1-9]|[12][0-9]|30))|(02(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))0229))\\d{3}(\\d|X)?$"; 25 private static final String pattern15_1 = "^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}$"; 26 private static final String pattern15_2 = "^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}$"; 27 private static final int[] rights = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1}; 28 private static final String[] checkDigits = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; 29 private static final String sSX[] = { "猪", "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗" }; 30 31 //省份编码集合 32 public static Map<String, String> cityCodes = new HashMap<String, String>(); 33 34 //台湾身份首字母对应数字 35 //public static Map<String, Integer> twFirstCode = new HashMap<String, Integer>(); 36 //香港身份首字母对应数字 37 //public static Map<String, Integer> hkFirstCode = new HashMap<String, Integer>(); 38 39 40 static { 41 cityCodes.put("11", "北京"); 42 cityCodes.put("12", "天津"); 43 cityCodes.put("13", "河北"); 44 cityCodes.put("14", "山西"); 45 cityCodes.put("15", "内蒙古"); 46 cityCodes.put("21", "辽宁"); 47 cityCodes.put("22", "吉林"); 48 cityCodes.put("23", "黑龙江"); 49 cityCodes.put("31", "上海"); 50 cityCodes.put("32", "江苏"); 51 cityCodes.put("33", "浙江"); 52 cityCodes.put("34", "安徽"); 53 cityCodes.put("35", "福建"); 54 cityCodes.put("36", "江西"); 55 cityCodes.put("37", "山东"); 56 cityCodes.put("41", "河南"); 57 cityCodes.put("42", "湖北"); 58 cityCodes.put("43", "湖南"); 59 cityCodes.put("44", "广东"); 60 cityCodes.put("45", "广西"); 61 cityCodes.put("46", "海南"); 62 cityCodes.put("50", "重庆"); 63 cityCodes.put("51", "四川"); 64 cityCodes.put("52", "贵州"); 65 cityCodes.put("53", "云南"); 66 cityCodes.put("54", "西藏"); 67 cityCodes.put("61", "陕西"); 68 cityCodes.put("62", "甘肃"); 69 cityCodes.put("63", "青海"); 70 cityCodes.put("64", "宁夏"); 71 cityCodes.put("65", "新疆"); 72 cityCodes.put("71", "台湾"); 73 cityCodes.put("81", "香港"); 74 cityCodes.put("82", "澳门"); 75 cityCodes.put("91", "国外"); 76 /*twFirstCode.put("A", 10); 77 twFirstCode.put("B", 11); 78 twFirstCode.put("C", 12); 79 twFirstCode.put("D", 13); 80 twFirstCode.put("E", 14); 81 twFirstCode.put("F", 15); 82 twFirstCode.put("G", 16); 83 twFirstCode.put("H", 17); 84 twFirstCode.put("J", 18); 85 twFirstCode.put("K", 19); 86 twFirstCode.put("L", 20); 87 twFirstCode.put("M", 21); 88 twFirstCode.put("N", 22); 89 twFirstCode.put("P", 23); 90 twFirstCode.put("Q", 24); 91 twFirstCode.put("R", 25); 92 twFirstCode.put("S", 26); 93 twFirstCode.put("T", 27); 94 twFirstCode.put("U", 28); 95 twFirstCode.put("V", 29); 96 twFirstCode.put("X", 30); 97 twFirstCode.put("Y", 31); 98 twFirstCode.put("W", 32); 99 twFirstCode.put("Z", 33); 100 twFirstCode.put("I", 34); 101 twFirstCode.put("O", 35); 102 hkFirstCode.put("A", 1); 103 hkFirstCode.put("B", 2); 104 hkFirstCode.put("C", 3); 105 hkFirstCode.put("R", 18); 106 hkFirstCode.put("U", 21); 107 hkFirstCode.put("Z", 26); 108 hkFirstCode.put("X", 24); 109 hkFirstCode.put("W", 23); 110 hkFirstCode.put("O", 15); 111 hkFirstCode.put("N", 14);*/ 112 } 113 114 115 116 117 /** 118 * description 验证身份证是否合法 119 * @param cardNo 身份证号 120 * @return true or false 121 * @author122 * @date 2019年9月20日 123 */ 124 public static boolean isValidIDCard(String cardNo) { 125 if (cardNo == null) { 126 return false; 127 } 128 switch (cardNo.length()) { 129 case 15 : 130 return verify15(cardNo); 131 case 18 : 132 return verify18(cardNo); 133 } 134 return false; 135 } 136 137 private static boolean verify15(String cardNo) { 138 if (cardNo.matches(pattern15_1)) { 139 return true; 140 } 141 return cardNo.matches(pattern15_2); 142 } 143 144 private static boolean verify18(String cardNo) { 145 if (cardNo.matches(pattern18)) { 146 return cardNo.substring(17).equalsIgnoreCase(getCheck_digit18(cardNo)); 147 } 148 return false; 149 } 150 private static String getCheck_digit18(String IDCardNO) { 151 int sum = 0; 152 for (int i = 0; i <= 16; i++) { 153 int num = Integer.parseInt(IDCardNO.substring(i, i + 1)); 154 int right = rights[i]; 155 sum += num * right; 156 } 157 int y = sum % 11; 158 return checkDigits[y]; 159 } 160 161 162 /** 163 * 根据身份证号获取生日年 164 * @param idCard 身份证号 165 * @return 生日(yyyy) 166 */ 167 public static String getYearByIdCard(String idCard) { 168 Integer len = idCard.length(); 169 if (len < CHINA_ID_MIN_LENGTH) { 170 return null; 171 } else if (len == CHINA_ID_MIN_LENGTH) { 172 idCard = conver15CardTo18(idCard); 173 } 174 return idCard.substring(6, 10); 175 } 176 177 /** 178 * 根据身份证号获取生日月 179 * @param idCard 身份证号 180 * @return 生日(MM) 181 */ 182 public static String getMonthByIdCard(String idCard) { 183 Integer len = idCard.length(); 184 if (len < CHINA_ID_MIN_LENGTH) { 185 return null; 186 } else if (len == CHINA_ID_MIN_LENGTH) { 187 idCard = conver15CardTo18(idCard); 188 } 189 return idCard.substring(10, 12); 190 } 191 192 /** 193 * 根据身份证号获取生日天 194 * @param idCard 身份证号 195 * @return 生日(dd) 196 */ 197 public static String getDateByIdCard(String idCard) { 198 Integer len = idCard.length(); 199 if (len < CHINA_ID_MIN_LENGTH) { 200 return null; 201 } else if (len == CHINA_ID_MIN_LENGTH) { 202 idCard = conver15CardTo18(idCard); 203 } 204 return idCard.substring(12, 14); 205 } 206 207 /** 208 * description 根据身份证获取获取年龄 209 * @param idCard 身份证号 210 * @return age 年龄 211 * @author212 * @date 2019年9月20日 213 */ 214 public static int getAgeByIdCard(String idCard) { 215 int iAge = 0; 216 if (idCard.length() == CHINA_ID_MIN_LENGTH) { 217 idCard = conver15CardTo18(idCard); 218 } 219 String year = idCard.substring(6, 10); 220 Calendar cal = Calendar.getInstance(); 221 int iCurrYear = cal.get(Calendar.YEAR); 222 iAge = iCurrYear - Integer.valueOf(year); 223 return iAge; 224 } 225 226 227 /** 228 * 根据身份证号获取性别 229 * @param idCard 身份证号 230 * @return 性别(M-男,F-女,N-未知) 231 */ 232 public static String getGenderByIdCard(String idCard) { 233 String sGender = "N"; 234 if (idCard.length() == CHINA_ID_MIN_LENGTH) { 235 idCard = conver15CardTo18(idCard); 236 } 237 String sCardNum = idCard.substring(16, 17); 238 if (Integer.parseInt(sCardNum) % 2 != 0) { 239 sGender = "M"; 240 } else { 241 sGender = "F"; 242 } 243 return sGender; 244 } 245 246 247 /** 248 * 根据身份证号获取户籍省份 249 * @param idCard 身份编码 250 * @return 省级编码。 251 */ 252 public static String getProvinceByIdCard(String idCard) { 253 int len = idCard.length(); 254 String sProvince = null; 255 String sProvinNum = ""; 256 if (len == CHINA_ID_MIN_LENGTH || len == CHINA_ID_MAX_LENGTH) { 257 sProvinNum = idCard.substring(0, 2); 258 } 259 sProvince = cityCodes.get(sProvinNum); 260 return sProvince; 261 } 262 263 /** 264 * 根据身份证号,自动获取对应的生肖 265 * @param idCard 身份证号码 266 * @return 生肖 267 */ 268 public static String getZodiacByIdCard(String idCard) { // 根据身份证号,自动返回对应的生肖 269 if (!isValidIDCard(idCard)){ 270 return "idCard error"; 271 } 272 int year = Integer.valueOf(getYearByIdCard(idCard)); 273 int end = 3; 274 int x = (year - end) % 12; 275 String retValue = ""; 276 retValue = sSX[x]; 277 return retValue; 278 } 279 /** 280 * 根据身份证号获取对应的星座 281 * @param idCard: 身份证号 282 * @return 星座 283 */ 284 public static String getConsteByIdCard(String idCard) { 285 String conste = ""; 286 if (idCard == null || !isValidIDCard(idCard)) { 287 return null; 288 } else { 289 Integer month = Integer.valueOf(getMonthByIdCard(idCard)); 290 Integer day = Integer.valueOf(getDateByIdCard(idCard)); 291 if ((month == 1 && day >= 20) || (month == 2 && day <= 18)) { 292 conste = "水瓶座"; 293 } else if ((month == 2 && day >= 19) || (month == 3 && day <= 20)) { 294 conste = "双鱼座"; 295 } else if ((month == 3 && day > 20) || (month == 4 && day <= 19)) { 296 conste = "白羊座"; 297 } else if ((month == 4 && day >= 20) || (month == 5 && day <= 20)) { 298 conste = "金牛座"; 299 } else if ((month == 5 && day >= 21) || (month == 6 && day <= 21)) { 300 conste = "双子座"; 301 } else if ((month == 6 && day > 21) || (month == 7 && day <= 22)) { 302 conste = "巨蟹座"; 303 } else if ((month == 7 && day > 22) || (month == 8 && day <= 22)) { 304 conste = "狮子座"; 305 } else if ((month == 8 && day >= 23) || (month == 9 && day <= 22)) { 306 conste = "处女座"; 307 } else if ((month == 9 && day >= 23) || (month == 10 && day <= 23)) { 308 conste = "天秤座"; 309 } else if ((month == 10 && day > 23) || (month == 11 && day <= 22)) { 310 conste = "天蝎座"; 311 } else if ((month == 11 && day > 22) || (month == 12 && day <= 21)) { 312 conste = "射手座"; 313 } else if ((month == 12 && day > 21) || (month == 1 && day <= 19)) { 314 conste = "摩羯座"; 315 } 316 return conste; 317 } 318 } 319 320 321 322 323 324 325 /** 326 * 根据身份证号获取生日 327 * @param idCard 身份证号 328 * @return 生日(yyyyMMdd) 329 */ 330 public static String getBirthByIdCard(String idCard){ 331 Integer len = idCard.length(); 332 if (len < CHINA_ID_MIN_LENGTH) { 333 return null; 334 } else if (len == CHINA_ID_MIN_LENGTH) { 335 idCard = conver15CardTo18(idCard); 336 } 337 return idCard.substring(6, 14); 338 } 339 /** 340 * 根据生日获取 生日年 yyyy 341 * @param IDBirthday yyyy-MM-dd 342 * @return year 年份 343 */ 344 public static String getYearByDate(String strDate){ 345 return strDate.substring(0,4); 346 } 347 /** 348 * 根据生日获取 生日月 MM 349 * @param IDBirthday yyyy-MM-dd 350 * @return month 351 */ 352 public static String getMonthByDate(String strDate){ 353 return strDate.substring(5,7); 354 } 355 /** 356 * 根据生日获取 生日天 dd 357 * @param IDBirthday yyyy-MM-dd 358 * @return 359 */ 360 public static String getDayByDate(String strDate){ 361 return strDate.substring(8,10); 362 } 363 364 /** 365 * 根据生日获取用户年龄 yyyy-MM-dd 366 * @param IDBirthday yyyy-MM-dd 367 * @return age 年龄 368 */ 369 public static Integer getAgeByDate(String strDate){ 370 String year = getYearByDate(strDate); 371 Calendar cal = Calendar.getInstance(); 372 Integer nowyear = cal.get(Calendar.YEAR); 373 Integer age = nowyear-Integer.valueOf(year); 374 return age; 375 } 376 /** 377 * description 根据生日获取生肖 378 * @param IDBirthday yyyy-MM-dd 379 * @return 380 * @author381 * @date 2019年9月20日 382 */ 383 public static String getZodiacByBirthday(String IDBirthday) { 384 int year = Integer.valueOf(getYearByDate(IDBirthday)); 385 int end = 3; 386 int x = (year - end) % 12; 387 String retValue = ""; 388 retValue = sSX[x]; 389 return retValue; 390 } 391 392 /** 393 * 根据生日(yyyy-MM-dd)获取对应的星座 394 * @param IDBirthday: (yyyy-MM-dd) 395 * @return 星座 396 */ 397 public static String getConsteByBirthday(String IDBirthday) { 398 String conste = ""; 399 if (IDBirthday == null) { 400 return null; 401 } else { 402 Integer month = Integer.valueOf(getMonthByDate(IDBirthday)); 403 Integer day = Integer.valueOf(getDayByDate(IDBirthday)); 404 if ((month == 1 && day >= 20) || (month == 2 && day <= 18)) { 405 conste = "水瓶座"; 406 } else if ((month == 2 && day >= 19) || (month == 3 && day <= 20)) { 407 conste = "双鱼座"; 408 } else if ((month == 3 && day > 20) || (month == 4 && day <= 19)) { 409 conste = "白羊座"; 410 } else if ((month == 4 && day >= 20) || (month == 5 && day <= 20)) { 411 conste = "金牛座"; 412 } else if ((month == 5 && day >= 21) || (month == 6 && day <= 21)) { 413 conste = "双子座"; 414 } else if ((month == 6 && day > 21) || (month == 7 && day <= 22)) { 415 conste = "巨蟹座"; 416 } else if ((month == 7 && day > 22) || (month == 8 && day <= 22)) { 417 conste = "狮子座"; 418 } else if ((month == 8 && day >= 23) || (month == 9 && day <= 22)) { 419 conste = "处女座"; 420 } else if ((month == 9 && day >= 23) || (month == 10 && day <= 23)) { 421 conste = "天秤座"; 422 } else if ((month == 10 && day > 23) || (month == 11 && day <= 22)) { 423 conste = "天蝎座"; 424 } else if ((month == 11 && day > 22) || (month == 12 && day <= 21)) { 425 conste = "射手座"; 426 } else if ((month == 12 && day > 21) || (month == 1 && day <= 19)) { 427 conste = "摩羯座"; 428 } 429 return conste; 430 } 431 } 432 433 /** 434 * description 传入生日 ,身份证有效期开始时间,截止时间,判断当前身份证是否在合法的年限范围内 435 * 证件的有效期限(未满十六周岁:五年;十六周岁至二十五周岁:十年;二十六周岁至四十五周岁:二十年;四十六周岁以上:长期) 436 * @param birthday yyyy-MM-dd 437 * @param str_Date yyyy-MM-dd 438 * @param end_Date yyyy-MM-dd Or 长期 439 * @return true Or false 440 * @author441 * @date 2019年3月20日 442 */ 443 public static boolean isLegalCard(String birthday,String str_Date,String end_Date){ 444 Integer age = getAgeByDate(birthday);//获取年龄 445 if(age <= 16){//未成年不允许开卡 446 return false; 447 } 448 //获取当前身份证的有效期 449 if("长期".equals(end_Date)){//长期的身份证-年龄应是四十六岁以上 450 if(age < 46){//长期期限 46岁以上 451 return false; 452 } 453 return true; 454 }else{//计算有效期限 455 String strYear = getYearByDate(str_Date);//开始年限 456 String endYear = getYearByDate(end_Date);//结束年限 457 //计算年限 458 Integer time_limit = Integer.valueOf(endYear) - Integer.valueOf(strYear); 459 switch (time_limit) { 460 case 5://5年期限年龄在20岁以下 461 return age <=20 ?true:false; 462 case 10://10年期限 16~35岁 463 return 16<=age && age <= 35?true:false; 464 case 20://20年期限 26~65岁 465 return 26<=age && age <= 65?true:false; 466 default: 467 break; 468 } 469 return false; 470 } 471 } 472 473 474 /** 475 * description 验证身份证地址与签发机关所在公安局是否一致 (签发机关截取(县/市/区)公安局之前的部分,获得地名) 476 * @param addr 地址 例:江苏省阜宁县益林镇杨园新村一巷2号 477 * @param issu_organ 签发机关公安局 例:阜宁县公安局 478 * 截取后的签发地为:阜宁 479 * @return true Or false 480 * @author481 * @date 2019年4月21日 482 */ 483 public static Boolean StringIsContainsStr(String addr,String issu_organ){ 484 if(addr == null || issu_organ == null || addr == "" || issu_organ == ""|| addr.equals("") || issu_organ.equals("") || issu_organ.length() <= 3){ 485 return false; 486 } 487 issu_organ = issu_organ.substring(0, issu_organ.lastIndexOf("公安")-1);//截取签发机关所在地 488 if(issu_organ.trim() == "" || issu_organ.trim().equals("")){ 489 return false; 490 } 491 if(addr.contains(issu_organ)){ 492 return true; 493 }else{ 494 return false; 495 } 496 } 497 498 499 /** 500 * 将15位身份证号码转换为18位 501 * @param idCard 15位身份编码 502 * @return 18 位身份编码 503 */ 504 public static String conver15CardTo18(String idCard) { 505 String idCard18 = ""; 506 if (idCard.length() != CHINA_ID_MIN_LENGTH) { 507 return null; 508 } 509 if (isNum(idCard)) { 510 // 获取出生年月日 511 String birthday = idCard.substring(6, 12); 512 Date birthDate = null; 513 try { 514 birthDate = new SimpleDateFormat("yyMMdd").parse(birthday); 515 } catch (Exception e) { 516 e.printStackTrace(); 517 } 518 Calendar cal = Calendar.getInstance(); 519 if (birthDate != null) 520 cal.setTime(birthDate); 521 // 获取出生年(完全表现形式,如:2010) 522 String sYear = String.valueOf(cal.get(Calendar.YEAR)); 523 idCard18 = idCard.substring(0, 6) + sYear + idCard.substring(8); 524 // 转换字符数组 525 char[] cArr = idCard18.toCharArray(); 526 if (cArr != null) { 527 int[] iCard = converCharToInt(cArr); 528 int iSum17 = getPowerSum(iCard); 529 // 获取校验位 530 String sVal = getCheckCode18(iSum17); 531 if (sVal.length() > 0) { 532 idCard18 += sVal; 533 } else { 534 return null; 535 } 536 } 537 } else { 538 return null; 539 } 540 return idCard18; 541 } 542 543 /** 544 * 数字验证 545 * 546 * @param val 547 * @return 提取的数字。 548 */ 549 public static boolean isNum(String val) { 550 return val == null || "".equals(val) ? false : val.matches("^[0-9]*{1}"); 551 } 552 553 public static int[] converCharToInt(char[] ca) { 554 int len = ca.length; 555 int[] iArr = new int[len]; 556 try { 557 for (int i = 0; i < len; i++) { 558 iArr[i] = Integer.parseInt(String.valueOf(ca[i])); 559 } 560 } catch (NumberFormatException e) { 561 e.printStackTrace(); 562 } 563 return iArr; 564 } 565 566 /** 567 * 将身份证的每位和对应位的加权因子相乘之后,再得到和值 568 * 569 * @param iArr 570 * @return 身份证编码。 571 */ 572 public static int getPowerSum(int[] iArr) { 573 int iSum = 0; 574 if (power.length == iArr.length) { 575 for (int i = 0; i < iArr.length; i++) { 576 for (int j = 0; j < power.length; j++) { 577 if (i == j) { 578 iSum = iSum + iArr[i] * power[j]; 579 } 580 } 581 } 582 } 583 return iSum; 584 } 585 /** 586 * 将power和值与11取模获得余数进行校验码判断 587 * 588 * @param iSum 589 * @return 校验位 590 */ 591 public static String getCheckCode18(int iSum) { 592 String sCode = ""; 593 switch (iSum % 11) { 594 case 10: 595 sCode = "2"; 596 break; 597 case 9: 598 sCode = "3"; 599 break; 600 case 8: 601 sCode = "4"; 602 break; 603 case 7: 604 sCode = "5"; 605 break; 606 case 6: 607 sCode = "6"; 608 break; 609 case 5: 610 sCode = "7"; 611 break; 612 case 4: 613 sCode = "8"; 614 break; 615 case 3: 616 sCode = "9"; 617 break; 618 case 2: 619 sCode = "x"; 620 break; 621 case 1: 622 sCode = "0"; 623 break; 624 case 0: 625 sCode = "1"; 626 break; 627 } 628 return sCode; 629 } 630 631 632 633 660 661 }

原文链接:https://www.cnblogs.com/itxs/p/12066536.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:面试官:请说一下对象锁和类锁的区别

下一篇:IDEA中使用Maven模板创建Maven WebApp项目并使用Tomact来运行项