1. 程式人生 > >身份證資訊驗證工具類

身份證資訊驗證工具類

  1. import java.text.SimpleDateFormat;
  2. import java.util.Calendar;
  3. import java.util.GregorianCalendar;
  4. import java.util.HashMap;
  5. import java.util.Map;
  6. import java.util.Scanner;
  7. import java.util.regex.Matcher;
  8. import java.util.regex.Pattern;
  9. /**
  10. * 身份證校驗工具
  11. * @author Gaoxueying
  12. */
  13. public class IdCheckUtil {
  14.             /*********************************** 身份證驗證開始 ****************************************/
  15.             /**
  16.              * 身份證號碼驗證 1、號碼的結構 公民身份號碼是特徵組合碼,由十七位數字本體碼和一位校驗碼組成。排列順序從左至右依次為:六位數字地址碼,
  17.              * 八位數字出生日期碼,三位數字順序碼和一位數字校驗碼。 2、地址碼(前六位數)
  18.              * 表示編碼物件常住戶口所在縣(市、旗、區)的行政區劃程式碼,按GB/T2260的規定執行。 3、出生日期碼(第七位至十四位)
  19.              * 表示編碼物件出生的年、月、日,按GB/T7408的規定執行,年、月、日程式碼之間不用分隔符。 4、順序碼(第十五位至十七位)
  20.              * 表示在同一地址碼所標識的區域範圍內,對同年、同月、同日出生的人編定的順序號, 順序碼的奇數分配給男性,偶數分配給女性。 5、校驗碼(第十八位數)
  21.              * (1)十七位數字本體碼加權求和公式 S = Sum(Ai * Wi), i = 0, ... , 16 ,先對前17位數字的權求和
  22.              * Ai:表示第i位置上的身份證號碼數字值 Wi:表示第i位置上的加權因子 Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4
  23.              * 2 (2)計算模 Y = mod(S, 11) (3)通過模得到對應的校驗碼 Y: 0 1 2 3 4 5 6 7 8 9 10 校驗碼: 1 0
  24.              * X 9 8 7 6 5 4 3 2
  25.              */
  26.             /**
  27.              * 功能:身份證的有效驗證
  28.              * 
  29.              * @param IDStr
  30.              *            身份證號
  31.              * [url=home.php?mod=space&uid=7300]@return[/url] 有效:返回"" 無效:返回String資訊
  32.              */
  33.             public static boolean IDCardValidate(String IDStr) {
  34.                 String errorInfo = "";// 記錄錯誤資訊
  35.                 String[] ValCodeArr = { "1", "0", "X", "9", "8", "7", "6", "5", "4",
  36.                         "3", "2" };
  37.                 String[] Wi = { "7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7",
  38.                         "9", "10", "5", "8", "4", "2" };
  39.                 String Ai = "";
  40.                 // ================ 號碼的長度 15位或18位 ================
  41.                 if (IDStr.length() != 15 && IDStr.length() != 18) {
  42.                     errorInfo = "身份證號碼長度應該為15位或18位。";
  43.                     return false;
  44.                 }
  45.                 // =======================(end)========================
  46.                 // ================ 數字 除最後以為都為數字 ================
  47.                 if (IDStr.length() == 18) {
  48.                     Ai = IDStr.substring(0, 17);
  49.                 } else if (IDStr.length() == 15) {
  50.                     Ai = IDStr.substring(0, 6) + "19" + IDStr.substring(6, 15);
  51.                 }
  52.                 if (isNumeric(Ai) == false) {
  53.                     errorInfo = "身份證15位號碼都應為數字 ; 18位號碼除最後一位外,都應為數字。";
  54.                     return false;
  55.                 }
  56.                 // =======================(end)========================
  57.                 // ================ 出生年月是否有效 ================
  58.                 String strYear = Ai.substring(6, 10);// 年份
  59.                 String strMonth = Ai.substring(10, 12);// 月份
  60.                 String strDay = Ai.substring(12, 14);// 月份
  61.                 if (isDate(strYear + "-" + strMonth + "-" + strDay) == false) {
  62.                     errorInfo = "身份證生日無效。";
  63.                     return false;
  64.                 }
  65.                 GregorianCalendar gc = new GregorianCalendar();
  66.                 SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");
  67.                 try {
  68.                     if ((gc.get(Calendar.YEAR) - Integer.parseInt(strYear)) > 150
  69.                             || (gc.getTime().getTime() - s.parse(
  70.                                     strYear + "-" + strMonth + "-" + strDay).getTime()) < 0) {
  71.                         errorInfo = "身份證生日不在有效範圍。";
  72.                         return false;
  73.                     }
  74.                 } catch (NumberFormatException e) {
  75.                     e.printStackTrace();
  76.                 } catch (java.text.ParseException e) {
  77.                     e.printStackTrace();
  78.                 }
  79.                 if (Integer.parseInt(strMonth) > 12 || Integer.parseInt(strMonth) == 0) {
  80.                     errorInfo = "身份證月份無效";
  81.                     return false;
  82.                 }
  83.                 if (Integer.parseInt(strDay) > 31 || Integer.parseInt(strDay) == 0) {
  84.                     errorInfo = "身份證日期無效";
  85.                     return false;
  86.                 }
  87.                 // =====================(end)=====================
  88.                 // ================ 地區碼時候有效 ================
  89.                 Map<String, String> h = GetAreaCode();
  90.                 if (h.get(Ai.substring(0, 2)) == null) {
  91.                     errorInfo = "身份證地區編碼錯誤。";
  92.                     return false;
  93.                 }
  94.                 // ==============================================
  95.                 // ================ 判斷最後一位的值 ================
  96.                 int TotalmulAiWi = 0;
  97.                 for (int i = 0; i < 17; i++) {
  98.                     TotalmulAiWi = TotalmulAiWi
  99.                             + Integer.parseInt(String.valueOf(Ai.charAt(i)))
  100.                             * Integer.parseInt(Wi[i]);
  101.                 }
  102.                 int modValue = TotalmulAiWi % 11;
  103.                 String strVerifyCode = ValCodeArr[modValue];
  104.                 Ai = Ai + strVerifyCode;
  105.                 if (IDStr.length() == 18) {
  106.                     if (Ai.equals(IDStr) == false) {
  107.                         errorInfo = "身份證無效,不是合法的身份證號碼";
  108.                         return false;
  109.                     }
  110.                 }
  111.                 // =====================(end)=====================
  112.                 return true;
  113.             }
  114.             /**
  115.              * 功能:設定地區編碼
  116.              * 
  117.              * @return Hashtable 物件
  118.              */
  119.             private static Map<String, String> GetAreaCode() {
  120.                     Map<String, String> hashtable = new HashMap<String, String>();
  121.                 hashtable.put("11", "北京");
  122.                 hashtable.put("12", "天津");
  123.                 hashtable.put("13", "河北");
  124.                 hashtable.put("14", "山西");
  125.                 hashtable.put("15", "內蒙古");
  126.                 hashtable.put("21", "遼寧");
  127.                 hashtable.put("22", "吉林");
  128.                 hashtable.put("23", "黑龍江");
  129.                 hashtable.put("31", "上海");
  130.                 hashtable.put("32", "江蘇");
  131.                 hashtable.put("33", "浙江");
  132.                 hashtable.put("34", "安徽");
  133.                 hashtable.put("35", "福建");
  134.                 hashtable.put("36", "江西");
  135.                 hashtable.put("37", "山東");
  136.                 hashtable.put("41", "河南");
  137.                 hashtable.put("42", "湖北");
  138.                 hashtable.put("43", "湖南");
  139.                 hashtable.put("44", "廣東");
  140.                 hashtable.put("45", "廣西");
  141.                 hashtable.put("46", "海南");
  142.                 hashtable.put("50", "重慶");
  143.                 hashtable.put("51", "四川");
  144.                 hashtable.put("52", "貴州");
  145.                 hashtable.put("53", "雲南");
  146.                 hashtable.put("54", "西藏");
  147.                 hashtable.put("61", "陝西");
  148.                 hashtable.put("62", "甘肅");
  149.                 hashtable.put("63", "青海");
  150.                 hashtable.put("64", "寧夏");
  151.                 hashtable.put("65", "新疆");
  152.                 hashtable.put("71", "臺灣");
  153.                 hashtable.put("81", "香港");
  154.                 hashtable.put("82", "澳門");
  155.                 hashtable.put("91", "國外");
  156.                 return hashtable;
  157.             }
  158.             /**
  159.              * 功能:判斷字串是否為數字
  160.              * 
  161.              * @param str
  162.              * @return
  163.              */
  164.             private static boolean isNumeric(String str) {
  165.                 Pattern pattern = Pattern.compile("[0-9]*");
  166.                 Matcher isNum = pattern.matcher(str);
  167.                 if (isNum.matches()) {
  168.                     return true;
  169.                 } else {
  170.                     return false;
  171.                 }
  172.             }
  173.             /**
  174.              * 功能:判斷字串是否為日期格式
  175.              * 
  176.              * @param str
  177.              * @return
  178.              */
  179.             public static boolean isDate(String strDate) {
  180.                     String regxStr="^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[0-9])|([1-2][0-3]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?[        DISCUZ_CODE_0        ]quot;;
  181.                     Pattern pattern = Pattern.compile(regxStr);
  182.                     Matcher m = pattern.matcher(strDate);
  183.                 if (m.matches()) {
  184.                     return true;
  185.                 } else {
  186.                     return false;
  187.                 }
  188.             }
  189.             /**
  190.              * @param args
  191.              * [url=home.php?mod=space&uid=2643633]@throws[/url] ParseException
  192.              */
  193.             @SuppressWarnings("static-access")
  194.             public static void main(String[] args) {
  195.                 // String IDCardNum="210102820826411";
  196.                 // String IDCardNum="210102198208264114";
  197.                 while (true) {
  198.                     Scanner input = new Scanner(System.in);
  199.                     String n = input.nextLine();
  200.                     if (n.equals("N") || n.equals("n")) {
  201.                         break;
  202.                     }
  203.                     String IDCardNum = input.nextLine();
  204.                     IdCheckUtil cc = new IdCheckUtil();
  205.                     System.out.println(cc.IDCardValidate(IDCardNum));
  206.                 }
  207.                 // System.out.println(cc.isDate("1996-02-29"));
  208.             }
  209.             /*********************************** 身份證驗證結束 ****************************************/