记录,备查!
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 = {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
|