public class IDCard { |
002 |
003 | private String _codeError; |
004 |
005 | //wi =2(n-1)(mod 11) |
006 | final int [] wi = { 7 , 9 , 10 , 5 , 8 , 4 , 2 , 1 , 6 , 3 , 7 , 9 , 10 , 5 , 8 , 4 , 2 , 1 }; |
007 | // verify digit |
008 | final int [] vi = { 1 , 0 , 'X' , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 }; |
009 | private int [] ai = new int [ 18 ]; |
010 | private static String[] _areaCode={ "11" , "12" , "13" , "14" , "15" , "21" , "22" |
011 | , "23" , "31" , "32" , "33" , "34" , "35" , "36" , "37" , "41" , "42" , "43" , "44" |
012 | , "45" , "46" , "50" , "51" , "52" , "53" , "54" , "61" , "62" , "63" , "64" , "65" , "71" , "81" , "82" , "91" }; |
013 | private static HashMap<String,Integer> dateMap; |
014 | private static HashMap<String,String> areaCodeMap; |
015 | static { |
016 | dateMap= new HashMap<String,Integer>(); |
017 | dateMap.put( "01" , 31 ); |
018 | dateMap.put( "02" , null ); |
019 | dateMap.put( "03" , 31 ); |
020 | dateMap.put( "04" , 30 ); |
021 | dateMap.put( "05" , 31 ); |
022 | dateMap.put( "06" , 30 ); |
023 | dateMap.put( "07" , 31 ); |
024 | dateMap.put( "08" , 31 ); |
025 | dateMap.put( "09" , 30 ); |
026 | dateMap.put( "10" , 31 ); |
027 | dateMap.put( "11" , 30 ); |
028 | dateMap.put( "12" , 31 ); |
029 | areaCodeMap= new HashMap<String,String>(); |
030 | for (String code:_areaCode){ |
031 | areaCodeMap.put(code, null ); |
032 | } |
033 | } |
034 |
035 | //验证身份证位数,15位和18位身份证 |
036 | public boolean verifyLength(String code){ |
037 | int length=code.length(); |
038 | if (length== 15 || length== 18 ){ |
039 | return true ; |
040 | } else { |
041 | _codeError= "错误:输入的身份证号不是15位和18位的" ; |
042 | return false ; |
043 | } |
044 | } |
045 |
046 | //判断地区码 |
047 | public boolean verifyAreaCode(String code){ |
048 | String areaCode=code.substring( 0 , 2 ); |
049 | // Element child= _areaCodeElement.getChild("_"+areaCode); |
050 | if (areaCodeMap.containsKey(areaCode)){ |
051 | return true ; |
052 | } else { |
053 | _codeError= "错误:输入的身份证号的地区码(1-2位)[" +areaCode+ "]不符合中国行政区划分代码规定(GB/T2260-1999)" ; |
054 | return false ; |
055 | } |
056 | } |
057 |
058 | //判断月份和日期 |
059 | public boolean verifyBirthdayCode(String code){ |
060 | //验证月份 |
061 | String month=code.substring( 10 , 12 ); |
062 | boolean isEighteenCode=( 18 ==code.length()); |
063 | if (!dateMap.containsKey(month)){ |
064 | _codeError= "错误:输入的身份证号" +(isEighteenCode? "(11-12位)" : "(9-10位)" )+ "不存在[" +month+ "]月份,不符合要求(GB/T7408)" ; |
065 | return false ; |
066 | } |
067 | //验证日期 |
068 | String dayCode=code.substring( 12 , 14 ); |
069 | Integer day=dateMap.get(month); |
070 | String yearCode=code.substring( 6 , 10 ); |
071 | Integer year=Integer.valueOf(yearCode); |
072 |
073 | //非2月的情况 |
074 | if (day!= null ){ |
075 | if (Integer.valueOf(dayCode)>day || Integer.valueOf(dayCode)< 1 ){ |
076 | _codeError= "错误:输入的身份证号" +(isEighteenCode? "(13-14位)" : "(11-13位)" )+ "[" +dayCode+ "]号不符合小月1-30天大月1-31天的规定(GB/T7408)" ; |
077 | return false ; |
078 | } |
079 | } |
080 | //2月的情况 |
081 | else { |
082 | //闰月的情况 |
083 | if ((year% 4 == 0 &&year% 100 != 0 )||(year% 400 == 0 )){ |
084 | if (Integer.valueOf(dayCode)> 29 || Integer.valueOf(dayCode)< 1 ){ |
085 | _codeError= "错误:输入的身份证号" +(isEighteenCode? "(13-14位)" : "(11-13位)" )+ "[" +dayCode+ "]号在" +year+ "闰年的情况下未符合1-29号的规定(GB/T7408)" ; |
086 | return false ; |
087 | } |
088 | } |
089 | //非闰月的情况 |
090 | else { |
091 | if (Integer.valueOf(dayCode) > 28 || Integer.valueOf(dayCode) < 1 ) { |
092 | _codeError= "错误:输入的身份证号" +(isEighteenCode? "(13-14位)" : "(11-13位)" )+ "[" +dayCode+ "]号在" +year+ "平年的情况下未符合1-28号的规定(GB/T7408)" ; |
093 | return false ; |
094 | } |
095 | } |
096 | } |
097 | return true ; |
098 | } |
099 |
100 | //验证身份除了最后位其他的是否包含字母 |
101 | public boolean containsAllNumber(String code) { |
102 | String str= "" ; |
103 | if (code.length()== 15 ){ |
104 | str=code.substring( 0 , 15 ); |
105 | } else if (code.length()== 18 ){ |
106 | str=code.substring( 0 , 17 ); |
107 | } |
108 | char [] ch = str.toCharArray(); |
109 | for ( int i = 0 ; i < ch.length; i++) { |
110 | if (! (ch[i] >= '0' && ch[i] <= '9' )) { |
111 | _codeError= "错误:输入的身份证号第" +(i+ 1 )+ "位包含字母" ; |
112 | return false ; |
113 | } |
114 | } |
115 | return true ; |
116 | } |
117 |
118 | public String getCodeError(){ |
119 | return _codeError; |
120 | } |
121 |
122 | //验证身份证 |
123 | public boolean verify(String idcard) { |
124 | _codeError= "" ; |
125 | //验证身份证位数,15位和18位身份证 |
126 | if (!verifyLength(idcard)){ |
127 | return false ; |
128 | } |
129 | //验证身份除了最后位其他的是否包含字母 |
130 | if (!containsAllNumber(idcard)){ |
131 | return false ; |
132 | } |
133 |
134 | //如果是15位的就转成18位的身份证 |
135 | String eifhteencard= "" ; |
136 | if (idcard.length() == 15 ) { |
137 | eifhteencard = uptoeighteen(idcard); |
138 | } else { |
139 | eifhteencard=idcard; |
140 | } |
141 | //验证身份证的地区码 |
142 | if (!verifyAreaCode(eifhteencard)){ |
143 | return false ; |
144 | } |
145 | //判断月份和日期 |
146 | if (!verifyBirthdayCode(eifhteencard)){ |
147 | return false ; |
148 | } |
149 | //验证18位校验码,校验码采用ISO 7064:1983,MOD 11-2 校验码系统 |
150 | if (!verifyMOD(eifhteencard)){ |
151 | return false ; |
152 | } |
153 | return true ; |
154 | } |
155 |
156 | //验证18位校验码,校验码采用ISO 7064:1983,MOD 11-2 校验码系统 |
157 | public boolean verifyMOD(String code){ |
158 | String verify = code.substring( 17 , 18 ); |
159 | if ( "x" .equals(verify)){ |
160 | code=code.replaceAll( "x" , "X" ); |
161 | verify= "X" ; |
162 | } |
163 | String verifyIndex=getVerify(code); |
164 | if (verify.equals(verifyIndex)) { |
165 | return true ; |
166 | } |
167 | // int x=17; |
168 | // if(code.length()==15){ |
169 | // x=14; |
170 | // } |
171 | _codeError= "错误:输入的身份证号最末尾的数字验证码错误" ; |
172 | return false ; |
173 | } |
174 |
175 | //获得校验位 |
176 | public String getVerify(String eightcardid) { |
177 | int remaining = 0 ; |
178 |
179 | if (eightcardid.length() == 18 ) { |
180 | eightcardid = eightcardid.substring( 0 , 17 ); |
181 | } |
182 |
183 | if (eightcardid.length() == 17 ) { |
184 | int sum = 0 ; |
185 | for ( int i = 0 ; i < 17 ; i++) { |
186 | String k = eightcardid.substring(i, i + 1 ); |
187 | ai[i] = Integer.parseInt(k); |
188 | } |
189 |
190 | for ( int i = 0 ; i < 17 ; i++) { |
191 | sum = sum + wi[i] * ai[i]; |
192 | } |
193 | remaining = sum % 11 ; |
194 | } |
195 |
196 | return remaining == 2 ? "X" : String.valueOf(vi[remaining]); |
197 | } |
198 |
199 | //15位转18位身份证 |
200 | public String uptoeighteen(String fifteencardid) { |
201 | String eightcardid = fifteencardid.substring( 0 , 6 ); |
202 | eightcardid = eightcardid + "19" ; |
203 | eightcardid = eightcardid + fifteencardid.substring( 6 , 15 ); |
204 | eightcardid = eightcardid + getVerify(eightcardid); |
205 | return eightcardid; |
206 | } |
207 |
208 |
209 |
210 | 调 用 new IDCard().verify(身份证id); |