Java 身份证号验证

  1 package utils;
  2 
  3 import java.util.HashMap;
  4 
  5 /**
  6  * Created by liqun.chen on 2017/3/15.
  7  */
  8 public class IdCardVerifyUtil {
  9 
 10     private String _codeError;
 11 
 12     //wi =2(n-1)(mod 11)
 13     final int[] wi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1};
 14     // verify digit
 15     final int[] vi = {1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2};
 16     private int[] ai = new int[18];
 17     private static String[] _areaCode = {"11", "12", "13", "14", "15", "21", "22"
 18             , "23", "31", "32", "33", "34", "35", "36", "37", "41", "42", "43", "44"
 19             , "45", "46", "50", "51", "52", "53", "54", "61", "62", "63", "64", "65", "71", "81", "82", "91"};
 20     private static HashMap<String, Integer> dateMap;
 21     private static HashMap<String, String> areaCodeMap;
 22 
 23     static {
 24         dateMap = new HashMap<String, Integer>();
 25         dateMap.put("01", 31);
 26         dateMap.put("02", null);
 27         dateMap.put("03", 31);
 28         dateMap.put("04", 30);
 29         dateMap.put("05", 31);
 30         dateMap.put("06", 30);
 31         dateMap.put("07", 31);
 32         dateMap.put("08", 31);
 33         dateMap.put("09", 30);
 34         dateMap.put("10", 31);
 35         dateMap.put("11", 30);
 36         dateMap.put("12", 31);
 37         areaCodeMap = new HashMap<String, String>();
 38         for (String code : _areaCode) {
 39             areaCodeMap.put(code, null);
 40         }
 41     }
 42 
 43     //验证身份证位数,15位和18位身份证
 44     public boolean verifyLength(String code) {
 45         int length = code.length();
 46         if (length == 15 || length == 18) {
 47             return true;
 48         } else {
 49             _codeError = "错误:输入的身份证号不是15位和18位的";
 50             return false;
 51         }
 52     }
 53 
 54     //判断地区码
 55     public boolean verifyAreaCode(String code) {
 56         String areaCode = code.substring(0, 2);
 57 //            Element child=  _areaCodeElement.getChild("_"+areaCode);
 58         if (areaCodeMap.containsKey(areaCode)) {
 59             return true;
 60         } else {
 61             _codeError = "错误:输入的身份证号的地区码(1-2位)[" + areaCode + "]不符合中国行政区划分代码规定(GB/T2260-1999)";
 62             return false;
 63         }
 64     }
 65 
 66     //判断月份和日期
 67     public boolean verifyBirthdayCode(String code) {
 68         //验证月份
 69         String month = code.substring(10, 12);
 70         boolean isEighteenCode = (18 == code.length());
 71         if (!dateMap.containsKey(month)) {
 72             _codeError = "错误:输入的身份证号" + (isEighteenCode ? "(11-12位)" : "(9-10位)") + "不存在[" + month + "]月份,不符合要求(GB/T7408)";
 73             return false;
 74         }
 75         //验证日期
 76         String dayCode = code.substring(12, 14);
 77         Integer day = dateMap.get(month);
 78         String yearCode = code.substring(6, 10);
 79         Integer year = Integer.valueOf(yearCode);
 80 
 81         //非2月的情况
 82         if (day != null) {
 83             if (Integer.valueOf(dayCode) > day || Integer.valueOf(dayCode) < 1) {
 84                 _codeError = "错误:输入的身份证号" + (isEighteenCode ? "(13-14位)" : "(11-13位)") + "[" + dayCode + "]号不符合小月1-30天大月1-31天的规定(GB/T7408)";
 85                 return false;
 86             }
 87         }
 88         //2月的情况
 89         else {
 90             //闰月的情况
 91             if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
 92                 if (Integer.valueOf(dayCode) > 29 || Integer.valueOf(dayCode) < 1) {
 93                     _codeError = "错误:输入的身份证号" + (isEighteenCode ? "(13-14位)" : "(11-13位)") + "[" + dayCode + "]号在" + year + "闰年的情况下未符合1-29号的规定(GB/T7408)";
 94                     return false;
 95                 }
 96             }
 97             //非闰月的情况
 98             else {
 99                 if (Integer.valueOf(dayCode) > 28 || Integer.valueOf(dayCode) < 1) {
100                     _codeError = "错误:输入的身份证号" + (isEighteenCode ? "(13-14位)" : "(11-13位)") + "[" + dayCode + "]号在" + year + "平年的情况下未符合1-28号的规定(GB/T7408)";
101                     return false;
102                 }
103             }
104         }
105         return true;
106     }
107 
108     //验证身份除了最后位其他的是否包含字母
109     public boolean containsAllNumber(String code) {
110         String str = "";
111         if (code.length() == 15) {
112             str = code.substring(0, 15);
113         } else if (code.length() == 18) {
114             str = code.substring(0, 17);
115         }
116         char[] ch = str.toCharArray();
117         for (int i = 0; i < ch.length; i++) {
118             if (!(ch[i] >= '0' && ch[i] <= '9')) {
119                 _codeError = "错误:输入的身份证号第" + (i + 1) + "位包含字母";
120                 return false;
121             }
122         }
123         return true;
124     }
125     public String getCodeError() {
126         return _codeError;
127     }
128     //验证18位校验码,校验码采用ISO 7064:1983,MOD 11-2 校验码系统
129     public boolean verifyMOD(String code) {
130         String verify = code.substring(17, 18);
131         if ("x".equals(verify)) {
132             code = code.replaceAll("x", "X");
133             verify = "X";
134         }
135         String verifyIndex = getVerify(code);
136         if (verify.equals(verifyIndex)) {
137             return true;
138         }
139 //            int x=17;
140 //            if(code.length()==15){
141 //                  x=14;
142 //            }
143         _codeError = "错误:输入的身份证号最末尾的数字验证码错误";
144         return false;
145     }
146 
147     //获得校验位
148     public String getVerify(String eightcardid) {
149         int remaining = 0;
150 
151         if (eightcardid.length() == 18) {
152             eightcardid = eightcardid.substring(0, 17);
153         }
154         if (eightcardid.length() == 17) {
155             int sum = 0;
156             for (int i = 0; i < 17; i++) {
157                 String k = eightcardid.substring(i, i + 1);
158                 ai[i] = Integer.parseInt(k);
159             }
160             for (int i = 0; i < 17; i++) {
161                 sum = sum + wi[i] * ai[i];
162             }
163             remaining = sum % 11;
164         }
165         return remaining == 2 ? "X" : String.valueOf(vi[remaining]);
166     }
167     //15位转18位身份证
168     public String uptoeighteen(String fifteencardid) {
169         String eightcardid = fifteencardid.substring(0, 6);
170         eightcardid = eightcardid + "19";
171         eightcardid = eightcardid + fifteencardid.substring(6, 15);
172         eightcardid = eightcardid + getVerify(eightcardid);
173         return eightcardid;
174     }
175     
176     //验证身份证
177     public boolean verify(String idcard) {
178         _codeError = "";
179         //验证身份证位数,15位和18位身份证
180         if (!verifyLength(idcard)) {
181             return false;
182         }
183         //验证身份除了最后位其他的是否包含字母
184         if (!containsAllNumber(idcard)) {
185             return false;
186         }
187         //如果是15位的就转成18位的身份证
188         String eifhteencard = "";
189         if (idcard.length() == 15) {
190             eifhteencard = uptoeighteen(idcard);
191         } else {
192             eifhteencard = idcard;
193         }
194         //验证身份证的地区码
195         if (!verifyAreaCode(eifhteencard)) {
196             return false;
197         }
198         //判断月份和日期
199         if (!verifyBirthdayCode(eifhteencard)) {
200             return false;
201         }
202         //验证18位校验码,校验码采用ISO 7064:1983,MOD 11-2 校验码系统
203         if (!verifyMOD(eifhteencard)) {
204             return false;
205         }
206         return true;
207     }
208 }

 

posted @ 2017-06-06 15:40  Mr..Chen  阅读(975)  评论(0编辑  收藏  举报