記錄,備查!
1 /**
2 * 文件描述:檢查身份證。
3 */
4 package com.baofeng.util;
5
6 import java.util.ArrayList;
7 import java.util.Calendar;
8 import java.util.HashMap;
9 import java.util.List;
10 import java.util.Map;
11 import java.util.regex.Matcher;
12 import java.util.regex.Pattern;
13
14 /**
15 * @author liuyf8688
16 *
17 */
18 public class IdCardUtil {
19
20 /** 省、市身份證號前兩位 **/
21 private static final Map<Integer, String> PROVINCE_AND_CITY = new HashMap<Integer, String>();
22 /** 判斷規范 **/
23 private static final Pattern CARD_NO_REG = Pattern.compile("(^\\d{15}$)|(^\\d{17}(\\d|x)$)");
24 /** 身份證15位時,次序為?。?位)市(3位)年(2位)月(2位)日(2位)校驗位(3位),皆為數字 **/
25 private final static Pattern FIFTEEN_BIRTHDAY = Pattern.compile("(\\d{6})(\\d{2})(\\d{2})(\\d{2})(\\d{3})");
26 /** 身份證18位時,次序為?。?位)市(3位)年(4位)月(2位)日(2位)校驗位(4位),校驗位末尾可能為x **/
27 private final static Pattern EIGHTEEN_BIRTHDAY = Pattern.compile("(\\d{6})(\\d{4})(\\d{2})(\\d{2})(\\d{3})([0-9]|x)");
28 /** 身份證本體位每位權值 */
29 private static final int[] powers = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
30 /** 校驗位候選值 */
31 private static final char[] parityBits = {'1', '0', 'x', '9', '8', '7', '6', '5', '4', '3', '2'};
32
33
34
35 public static boolean isValid(String cardNo) {
36 return isCardNo(cardNo) && checkProvince(cardNo) && checkBirthday(cardNo) && checkParity(cardNo);
37 }
38
39 /**
40 * 功能描述:判斷規范
41 * @param cardNo
42 * @return
43 */
44 private static boolean isCardNo(String cardNo) {
45 return CARD_NO_REG.matcher(cardNo).matches();
46 }
47
48 /**
49 * 功能描述:判斷省份
50 * @param cardNo
51 * @return
52 */
53 private static boolean checkProvince(String cardNo) {
54 if(PROVINCE_AND_CITY.get(Integer.valueOf(cardNo.substring(0, 2))) != null) {
55 return true;
56 }
57 return false;
58 }
59
60 /**
61 * 功能描述:判斷生日是否正確
62 * @param cardNo
63 * @return
64 */
65 private static boolean checkBirthday(String cardNo) {
66
67 String[] groups = splitToGroups(cardNo);
68 //
69 if(cardNo.length() == 15) {
70 int year = 1900 + Integer.valueOf(groups[2]);
71 int month = Integer.valueOf(groups[3]);
72 int day = Integer.valueOf(groups[4]);
73 Calendar calendar = Calendar.getInstance();
74 calendar.set(year, month, day);
75 return verifyBirthday(year, month, day, calendar);
76 }
77 //
78 if(cardNo.length() == 18) {
79
80 int year = Integer.valueOf(groups[2]);
81 int month = Integer.valueOf(groups[3]);
82 int day = Integer.valueOf(groups[4]);
83 Calendar calendar = Calendar.getInstance();
84 calendar.set(year, month - 1, day);
85 return verifyBirthday(year, month, day, calendar);
86 }
87
88 return false;
89 }
90
91 /**
92 * 功能:檢驗出生日期
93 * @param year
94 * @param month
95 * @param day
96 * @param calendar
97 * @return
98 */
99 private static boolean verifyBirthday(int year, int month, int day, Calendar calendar) {
100
101 if((calendar.get(Calendar.YEAR) == year)
102 && ((calendar.get(Calendar.MONTH) + 1) == month)
103 && (calendar.get(Calendar.DAY_OF_MONTH) == day)) {
104 int currYear = Calendar.getInstance().get(Calendar.YEAR);
105 int age = currYear - year;
106 if((age >= 3) && (age <=100)) {
107 return true;
108 }
109 }
110 return false;
111 }
112
113 /**
114 * 功能:判斷身份證號碼的校驗位是否正確
115 * @param cardNo
116 * @return
117 */
118 private static boolean checkParity(String cardNo) {
119 //
120 if(cardNo.length() == 15) {
121 cardNo = convert15To18Bit(cardNo);
122 }
123 //
124 int digitalCode = 0;
125 if(cardNo.length() == 18) {
126 for(int i = 0; i < 17; i ++) {
127 digitalCode += Integer.valueOf(cardNo.substring(i, i + 1)) * powers[i];
128 }
129 //
130 if(cardNo.substring(17, 18).equals(String.valueOf(parityBits[digitalCode % 11]))){
131 return true;
132 }
133 }
134 return false;
135 }
136
137 /**
138 * 功能:將15身份證號碼轉換成18位
139 * @param cardNo
140 * @return
141 */
142 private static String convert15To18Bit(String cardNo) {
143
144 cardNo = cardNo.substring(0, 6) + "19" + cardNo.substring(6, cardNo.length());
145 //
146 int digitalCode = 0;
147 for(int i = 0; i < 17; i ++) {
148 digitalCode += Integer.valueOf(cardNo.substring(i, i + 1)) * powers[i];
149 }
150 //
151 cardNo += parityBits[digitalCode % 11];
152 return cardNo;
153 }
154
155 /**
156 * 功能描述:將身份證號按照正則表達式分組。
157 * @param cardNo
158 * @return
159 */
160 private static String[] splitToGroups(String cardNo) {
161
162 List<String> groups = new ArrayList<String>();
163 //
164 if(cardNo.length() == 15) {
165 Matcher matcher = FIFTEEN_BIRTHDAY.matcher(cardNo);
166 boolean matchFound = matcher.find();
167 if (matchFound) {
168 for (int i=0; i<=matcher.groupCount(); i++) {
169 groups.add(matcher.group(i));
170 }
171 }
172 }
173 //
174 if(cardNo.length() == 18) {
175 Matcher matcher = EIGHTEEN_BIRTHDAY.matcher(cardNo);
176 boolean matchFound = matcher.find();
177 if (matchFound) {
178 for (int i=0; i<=matcher.groupCount(); i++) {
179 groups.add(matcher.group(i));
180 }
181 }
182 }
183
184 return groups.toArray(new String[0]);
185 }
186
187 static{
188 //11:"北京",12:"天津",13:"河北",14:"山西",15:"內蒙古",21:"遼寧",22:"吉林",23:"黑龍江",31:"上海",32:"江蘇",
189 PROVINCE_AND_CITY.put(11, "北京");
190 PROVINCE_AND_CITY.put(12, "天津");
191 PROVINCE_AND_CITY.put(13, "河北");
192 PROVINCE_AND_CITY.put(14, "山西");
193 PROVINCE_AND_CITY.put(15, "內蒙古");
194 PROVINCE_AND_CITY.put(21, "遼寧");
195 PROVINCE_AND_CITY.put(22, "吉林");
196 PROVINCE_AND_CITY.put(23, "黑龍江");
197 PROVINCE_AND_CITY.put(31, "上海");
198 PROVINCE_AND_CITY.put(32, "江蘇");
199 //33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山東",41:"河南",42:"湖北",43:"湖南",44:"廣東",45:"廣西",
200 PROVINCE_AND_CITY.put(33, "浙江");
201 PROVINCE_AND_CITY.put(34, "安徽");
202 PROVINCE_AND_CITY.put(35, "福建");
203 PROVINCE_AND_CITY.put(36, "江西");
204 PROVINCE_AND_CITY.put(37, "山東");
205 PROVINCE_AND_CITY.put(41, "河南");
206 PROVINCE_AND_CITY.put(42, "湖北");
207 PROVINCE_AND_CITY.put(43, "湖南");
208 PROVINCE_AND_CITY.put(44, "廣東");
209 PROVINCE_AND_CITY.put(45, "廣西");
210 //46:"海南",50:"重慶",51:"四川",52:"貴州",53:"云南",54:"西藏",61:"陜西",62:"甘肅",63:"青海",64:"寧夏",
211 PROVINCE_AND_CITY.put(46, "海南");
212 PROVINCE_AND_CITY.put(50, "重慶");
213 PROVINCE_AND_CITY.put(51, "四川");
214 PROVINCE_AND_CITY.put(52, "貴州");
215 PROVINCE_AND_CITY.put(53, "云南");
216 PROVINCE_AND_CITY.put(54, "西藏");
217 PROVINCE_AND_CITY.put(61, "陜西");
218 PROVINCE_AND_CITY.put(62, "甘肅");
219 PROVINCE_AND_CITY.put(63, "青海");
220 PROVINCE_AND_CITY.put(64, "寧夏");
221 //65:"新疆",71:"臺灣",81:"香港",82:"澳門",91:"國外"
222 PROVINCE_AND_CITY.put(65, "新疆");
223 PROVINCE_AND_CITY.put(71, "臺灣");
224 PROVINCE_AND_CITY.put(81, "香港");
225 PROVINCE_AND_CITY.put(82, "澳門");
226 PROVINCE_AND_CITY.put(91, "國外");
227 }
228 }
229
2 * 文件描述:檢查身份證。
3 */
4 package com.baofeng.util;
5
6 import java.util.ArrayList;
7 import java.util.Calendar;
8 import java.util.HashMap;
9 import java.util.List;
10 import java.util.Map;
11 import java.util.regex.Matcher;
12 import java.util.regex.Pattern;
13
14 /**
15 * @author liuyf8688
16 *
17 */
18 public class IdCardUtil {
19
20 /** 省、市身份證號前兩位 **/
21 private static final Map<Integer, String> PROVINCE_AND_CITY = new HashMap<Integer, String>();
22 /** 判斷規范 **/
23 private static final Pattern CARD_NO_REG = Pattern.compile("(^\\d{15}$)|(^\\d{17}(\\d|x)$)");
24 /** 身份證15位時,次序為?。?位)市(3位)年(2位)月(2位)日(2位)校驗位(3位),皆為數字 **/
25 private final static Pattern FIFTEEN_BIRTHDAY = Pattern.compile("(\\d{6})(\\d{2})(\\d{2})(\\d{2})(\\d{3})");
26 /** 身份證18位時,次序為?。?位)市(3位)年(4位)月(2位)日(2位)校驗位(4位),校驗位末尾可能為x **/
27 private final static Pattern EIGHTEEN_BIRTHDAY = Pattern.compile("(\\d{6})(\\d{4})(\\d{2})(\\d{2})(\\d{3})([0-9]|x)");
28 /** 身份證本體位每位權值 */
29 private static final int[] powers = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
30 /** 校驗位候選值 */
31 private static final char[] parityBits = {'1', '0', 'x', '9', '8', '7', '6', '5', '4', '3', '2'};
32
33
34
35 public static boolean isValid(String cardNo) {
36 return isCardNo(cardNo) && checkProvince(cardNo) && checkBirthday(cardNo) && checkParity(cardNo);
37 }
38
39 /**
40 * 功能描述:判斷規范
41 * @param cardNo
42 * @return
43 */
44 private static boolean isCardNo(String cardNo) {
45 return CARD_NO_REG.matcher(cardNo).matches();
46 }
47
48 /**
49 * 功能描述:判斷省份
50 * @param cardNo
51 * @return
52 */
53 private static boolean checkProvince(String cardNo) {
54 if(PROVINCE_AND_CITY.get(Integer.valueOf(cardNo.substring(0, 2))) != null) {
55 return true;
56 }
57 return false;
58 }
59
60 /**
61 * 功能描述:判斷生日是否正確
62 * @param cardNo
63 * @return
64 */
65 private static boolean checkBirthday(String cardNo) {
66
67 String[] groups = splitToGroups(cardNo);
68 //
69 if(cardNo.length() == 15) {
70 int year = 1900 + Integer.valueOf(groups[2]);
71 int month = Integer.valueOf(groups[3]);
72 int day = Integer.valueOf(groups[4]);
73 Calendar calendar = Calendar.getInstance();
74 calendar.set(year, month, day);
75 return verifyBirthday(year, month, day, calendar);
76 }
77 //
78 if(cardNo.length() == 18) {
79
80 int year = Integer.valueOf(groups[2]);
81 int month = Integer.valueOf(groups[3]);
82 int day = Integer.valueOf(groups[4]);
83 Calendar calendar = Calendar.getInstance();
84 calendar.set(year, month - 1, day);
85 return verifyBirthday(year, month, day, calendar);
86 }
87
88 return false;
89 }
90
91 /**
92 * 功能:檢驗出生日期
93 * @param year
94 * @param month
95 * @param day
96 * @param calendar
97 * @return
98 */
99 private static boolean verifyBirthday(int year, int month, int day, Calendar calendar) {
100
101 if((calendar.get(Calendar.YEAR) == year)
102 && ((calendar.get(Calendar.MONTH) + 1) == month)
103 && (calendar.get(Calendar.DAY_OF_MONTH) == day)) {
104 int currYear = Calendar.getInstance().get(Calendar.YEAR);
105 int age = currYear - year;
106 if((age >= 3) && (age <=100)) {
107 return true;
108 }
109 }
110 return false;
111 }
112
113 /**
114 * 功能:判斷身份證號碼的校驗位是否正確
115 * @param cardNo
116 * @return
117 */
118 private static boolean checkParity(String cardNo) {
119 //
120 if(cardNo.length() == 15) {
121 cardNo = convert15To18Bit(cardNo);
122 }
123 //
124 int digitalCode = 0;
125 if(cardNo.length() == 18) {
126 for(int i = 0; i < 17; i ++) {
127 digitalCode += Integer.valueOf(cardNo.substring(i, i + 1)) * powers[i];
128 }
129 //
130 if(cardNo.substring(17, 18).equals(String.valueOf(parityBits[digitalCode % 11]))){
131 return true;
132 }
133 }
134 return false;
135 }
136
137 /**
138 * 功能:將15身份證號碼轉換成18位
139 * @param cardNo
140 * @return
141 */
142 private static String convert15To18Bit(String cardNo) {
143
144 cardNo = cardNo.substring(0, 6) + "19" + cardNo.substring(6, cardNo.length());
145 //
146 int digitalCode = 0;
147 for(int i = 0; i < 17; i ++) {
148 digitalCode += Integer.valueOf(cardNo.substring(i, i + 1)) * powers[i];
149 }
150 //
151 cardNo += parityBits[digitalCode % 11];
152 return cardNo;
153 }
154
155 /**
156 * 功能描述:將身份證號按照正則表達式分組。
157 * @param cardNo
158 * @return
159 */
160 private static String[] splitToGroups(String cardNo) {
161
162 List<String> groups = new ArrayList<String>();
163 //
164 if(cardNo.length() == 15) {
165 Matcher matcher = FIFTEEN_BIRTHDAY.matcher(cardNo);
166 boolean matchFound = matcher.find();
167 if (matchFound) {
168 for (int i=0; i<=matcher.groupCount(); i++) {
169 groups.add(matcher.group(i));
170 }
171 }
172 }
173 //
174 if(cardNo.length() == 18) {
175 Matcher matcher = EIGHTEEN_BIRTHDAY.matcher(cardNo);
176 boolean matchFound = matcher.find();
177 if (matchFound) {
178 for (int i=0; i<=matcher.groupCount(); i++) {
179 groups.add(matcher.group(i));
180 }
181 }
182 }
183
184 return groups.toArray(new String[0]);
185 }
186
187 static{
188 //11:"北京",12:"天津",13:"河北",14:"山西",15:"內蒙古",21:"遼寧",22:"吉林",23:"黑龍江",31:"上海",32:"江蘇",
189 PROVINCE_AND_CITY.put(11, "北京");
190 PROVINCE_AND_CITY.put(12, "天津");
191 PROVINCE_AND_CITY.put(13, "河北");
192 PROVINCE_AND_CITY.put(14, "山西");
193 PROVINCE_AND_CITY.put(15, "內蒙古");
194 PROVINCE_AND_CITY.put(21, "遼寧");
195 PROVINCE_AND_CITY.put(22, "吉林");
196 PROVINCE_AND_CITY.put(23, "黑龍江");
197 PROVINCE_AND_CITY.put(31, "上海");
198 PROVINCE_AND_CITY.put(32, "江蘇");
199 //33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山東",41:"河南",42:"湖北",43:"湖南",44:"廣東",45:"廣西",
200 PROVINCE_AND_CITY.put(33, "浙江");
201 PROVINCE_AND_CITY.put(34, "安徽");
202 PROVINCE_AND_CITY.put(35, "福建");
203 PROVINCE_AND_CITY.put(36, "江西");
204 PROVINCE_AND_CITY.put(37, "山東");
205 PROVINCE_AND_CITY.put(41, "河南");
206 PROVINCE_AND_CITY.put(42, "湖北");
207 PROVINCE_AND_CITY.put(43, "湖南");
208 PROVINCE_AND_CITY.put(44, "廣東");
209 PROVINCE_AND_CITY.put(45, "廣西");
210 //46:"海南",50:"重慶",51:"四川",52:"貴州",53:"云南",54:"西藏",61:"陜西",62:"甘肅",63:"青海",64:"寧夏",
211 PROVINCE_AND_CITY.put(46, "海南");
212 PROVINCE_AND_CITY.put(50, "重慶");
213 PROVINCE_AND_CITY.put(51, "四川");
214 PROVINCE_AND_CITY.put(52, "貴州");
215 PROVINCE_AND_CITY.put(53, "云南");
216 PROVINCE_AND_CITY.put(54, "西藏");
217 PROVINCE_AND_CITY.put(61, "陜西");
218 PROVINCE_AND_CITY.put(62, "甘肅");
219 PROVINCE_AND_CITY.put(63, "青海");
220 PROVINCE_AND_CITY.put(64, "寧夏");
221 //65:"新疆",71:"臺灣",81:"香港",82:"澳門",91:"國外"
222 PROVINCE_AND_CITY.put(65, "新疆");
223 PROVINCE_AND_CITY.put(71, "臺灣");
224 PROVINCE_AND_CITY.put(81, "香港");
225 PROVINCE_AND_CITY.put(82, "澳門");
226 PROVINCE_AND_CITY.put(91, "國外");
227 }
228 }
229