Java 身份證驗證及獲取出生日期、性別
阿新 • • 發佈:2019-01-29
廢話不多說,直接上程式碼,程式碼很簡單,不多說廢話了
package com.ngupcc.commons.util; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.regex.Pattern; /** * 身份證工具類,由於現在使用的是二代身份證,所以只驗證18位<br> * 身份證號碼中涉及到行政區劃程式碼,程式碼不能驗證其是否真實存在,所以我們只能驗證身份號碼邏輯正確性, * 並不能驗證身份證號碼是否真實存在<br> * * ①地址碼:(前6位)所在縣(市、旗、區)的行政區劃程式碼 * ②出生日期碼:(第7位到第14位) * ③順序碼:(第15位到17位)縣、區級政府所轄派出所的分配碼 * ④校驗碼:(最後1位) * @autor zhouqibing * @time 2018-01-13 21:29 **/ public class IDCardUtils { // 正則格式 private static Pattern pattern = Pattern.compile("^\\d{17}[\\d|X]$"); /** * 省、直轄市程式碼表,身份證號的前6位為地址資訊,我們只驗證前兩位 */ private static final String CITY_CODE[] = { "11", "12", "13", "14", "15", "21", "22", "23", "31", "32", "33", "34", "35", "36", "37", "41", "42", "43", "44", "45", "46", "50", "51", "52", "53", "54", "61", "62", "63", "64", "65", "71", "81", "82", "91" }; /** * 每位加權因子 */ private static final int POWER[] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; /** * 第18位校檢碼 **/ private static final String VERIFY_CODE[] = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; /** * 驗證身份證 * @param idno * @return */ public static boolean verify(String idno){ //1.格式驗證 if(idno == null || !pattern.matcher(idno = idno.toUpperCase()).matches()){ return false; } //2.驗證省、直轄市程式碼。市、區不作驗證,沒有規則限制,數字即可 if(Arrays.binarySearch(CITY_CODE, idno.substring(0, 2)) == -1){ return false; } //3.驗證生日,生日可能存在輸入20180231這種情況,所以使用Calendar處理校驗 String birthday = idno.substring(6, 14); // 如果輸入的日期為20180231,通過轉換的後realBirthday為20180303 Date realBirthday = toBirthDay(birthday); // 轉換失敗或不相等 if(realBirthday == null || !birthday.equals(new SimpleDateFormat("yyyyMMdd").format(realBirthday))){ return false; } //4.順序碼不作驗證,沒有規則限制,數字即可 //5.驗證位驗證,計算規則為:身份證前17位數字,對應乘以每位的權重因子,然後相加得到數值X,與11取模獲得餘數,得到數值Y,通過Y得到校驗碼。 String verifyCode = VERIFY_CODE[getPowerSum(idno) % 11]; if(!verifyCode.equals(idno.substring(17, 18))){ return false; } return true; } /** * 取得身份證號前17位與對應的權重值相乘的和 * @return */ private static int getPowerSum(String idno){ int sum = 0; // 身份證前17位 char[] fix17 = idno.substring(0, 17).toCharArray(); for(int i = 0 ; i <= 16 ; i++){ sum += (Integer.parseInt(fix17[i] + "") * POWER[i]); } return sum; } /** * 轉換成日期 * @param birthday * @return */ private static Date toBirthDay(String birthday){ try{ Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.YEAR, Integer.parseInt(birthday.substring(0, 4))); calendar.set(Calendar.MONTH, Integer.parseInt(birthday.substring(4, 6)) - 1);//月份從0開始,所以減1 calendar.set(Calendar.DAY_OF_MONTH, Integer.parseInt(birthday.substring(6, 8))); //以下設定意義不大 calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); return calendar.getTime(); }catch (Exception e){ return null; } } /** * 從身份證號碼中獲取生日 * @param idno * @return null表示idno錯誤,未獲取到生日 */ public static Date getBirthDay(String idno){ if(!verify(idno)){ return null; } return toBirthDay(idno.substring(6, 14)); } /** * 從身份證號中獲取性別 * @param idno * @return 0:獲取失敗,1:男,2:女 */ public static int getGender(String idno){ if(!verify(idno)){ return 0; } // 奇男,偶女 return (Integer.parseInt(idno.substring(16, 17)) % 2) == 0 ? 2 : 1; } }