记录,备查!  

  
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位)市(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位)市(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 = {7910584216379105842};
 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(02))) != 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(1718).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(06+ "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