Advertisement
Guest User

Untitled

a guest
Jan 20th, 2017
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.59 KB | None | 0 0
  1. package demo.tool;
  2.  
  3. import java.text.ParseException;
  4. import java.text.SimpleDateFormat;
  5. import java.util.Date;
  6. import java.util.HashMap;
  7. import java.util.Map;
  8.  
  9. import org.slf4j.Logger;
  10. import org.slf4j.LoggerFactory;
  11.  
  12. import demo.constants.Gender;
  13. import demo.exception.InvalidParameterException;
  14. import demo.entity.IDCertNoValidateResult;
  15.  
  16. public class IDCertNoTool {
  17.  
  18. private static final Logger LOGGER = LoggerFactory.getLogger(IDCertNoTool.class);
  19.  
  20. public static final String INVALID_FIELD_NAME_CERT_NO = "certNo";
  21. public static final String INVALID_FIELD_NAME_AREA_CODE = "areaCode";
  22. public static final String INVALID_FIELD_NAME_BIRTHDAY = "birthday";
  23. public static final String INVALID_FIELD_NAME_CHECK_CHAR = "checkChar";
  24. public static final String INVALID_FIELD_NAME_GENDER = "gender";
  25.  
  26. private final static char[] PARITYBIT = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
  27. private final static int[] POWER_LIST = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
  28. private final static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMddHHmmssSSS") {
  29. private static final long serialVersionUID = 1L;
  30. {
  31. this.setLenient(false);
  32. }
  33. };
  34. private final static String BIRTHDAY_PADDING = "000000000";
  35. private final static Map<String, String> ZONE_NUMBER = new HashMap<String, String>() {
  36. private static final long serialVersionUID = 1L;
  37. {
  38. this.put("11", "北京");
  39. this.put("12", "天津");
  40. this.put("13", "河北");
  41. this.put("14", "山西");
  42. this.put("15", "内蒙古");
  43. this.put("21", "辽宁");
  44. this.put("22", "吉林");
  45. this.put("23", "黑龙江");
  46. this.put("31", "上海");
  47. this.put("32", "江苏");
  48. this.put("33", "浙江");
  49. this.put("34", "安徽");
  50. this.put("35", "福建");
  51. this.put("36", "江西");
  52. this.put("37", "山东");
  53. this.put("41", "河南");
  54. this.put("42", "湖北");
  55. this.put("43", "湖南");
  56. this.put("44", "广东");
  57. this.put("45", "广西");
  58. this.put("46", "海南");
  59. this.put("50", "重庆");
  60. this.put("51", "四川");
  61. this.put("52", "贵州");
  62. this.put("53", "云南");
  63. this.put("54", "西藏");
  64. this.put("61", "陕西");
  65. this.put("62", "甘肃");
  66. this.put("63", "青海");
  67. this.put("64", "宁夏");
  68. this.put("65", "新疆");
  69. this.put("71", "台湾");
  70. this.put("81", "香港");
  71. this.put("82", "澳门");
  72. this.put("91", "外国");
  73. }
  74. };
  75.  
  76.  
  77. public static enum IDCertNoType {
  78. OLD(15),
  79. NEW(18);
  80.  
  81. private int length;
  82.  
  83. private IDCertNoType(int length) {
  84. this.length = length;
  85. }
  86.  
  87. public int getLength() {
  88. return length;
  89. }
  90.  
  91. public static IDCertNoType resolve(int length) {
  92. for (IDCertNoType role : values()) {
  93. if (role.getLength() == length) {
  94. return role;
  95. }
  96. }
  97. throw new IllegalArgumentException("unknown cert number type for length: " + length);
  98. }
  99.  
  100. }
  101.  
  102. /**
  103. * 身份证验证,验证通过,返回性别和出生日期
  104. *
  105. * @param certNo 号码内容
  106. * @return 身份证中包含的性别和生日信息
  107. */
  108. public static IDCertNoValidateResult validate(String certNo) throws InvalidParameterException {
  109. char[] chars = certNo.toCharArray();
  110. int certNoLength = chars.length;
  111. IDCertNoType certNoType = null;
  112. try {
  113. certNoType = IDCertNoType.resolve(certNoLength);
  114. } catch (Exception e) {
  115. String msg = "invalid cert number length: " + certNoLength;
  116. LOGGER.error(msg);
  117. Map<String, String> errorDesc = new HashMap<>();
  118. errorDesc.put(INVALID_FIELD_NAME_CERT_NO, msg);
  119. throw new InvalidParameterException(errorDesc);
  120. }
  121.  
  122. switch (certNoType) {
  123. case OLD:
  124. return validateOldCertNo(chars);
  125.  
  126. case NEW:
  127. return validateNewCertNo(chars);
  128.  
  129. default: {
  130. String msg = "unsupported IDCertNoType: " + certNoType;
  131. LOGGER.error(msg);
  132. Map<String, String> errorDesc = new HashMap<>();
  133. errorDesc.put(INVALID_FIELD_NAME_CERT_NO, msg);
  134. throw new InvalidParameterException(errorDesc);
  135. }
  136. }
  137. }
  138.  
  139. private static IDCertNoValidateResult validateNewCertNo(char[] chars) throws InvalidParameterException {
  140. checkAreaCode(chars, 0, 6);
  141.  
  142. String birthdayStr = new String(chars, 6, 8) + BIRTHDAY_PADDING;
  143. Date birthday = parseBirthday(birthdayStr);
  144.  
  145. Gender gender = parseGender(chars[16]);
  146.  
  147. validateCheckChar(chars);
  148.  
  149. return new IDCertNoValidateResult(gender, birthday);
  150. }
  151.  
  152. /**
  153. * 校验旧版身份证号,这里在处理年龄时,会根据年龄位进行判断,若是"0x"则补充为"200x",否则补充为"19xx"。
  154. *
  155. * @param certNo 旧版身份证号
  156. * @return
  157. * @throws InvalidParameterException
  158. */
  159. private static IDCertNoValidateResult validateOldCertNo(char[] chars) throws InvalidParameterException {
  160. checkAreaCode(chars, 0, 6);
  161.  
  162. StringBuilder birthdayBuilder = new StringBuilder();
  163. char firstBirthdayChar = chars[6];
  164. switch (firstBirthdayChar) {
  165. case '0':
  166. birthdayBuilder.append("20").append(chars, 6, 6).append(BIRTHDAY_PADDING);
  167. break;
  168.  
  169. default:
  170. birthdayBuilder.append("19").append(chars, 6, 6).append(BIRTHDAY_PADDING);
  171. break;
  172. }
  173. Date birthday = parseBirthday(birthdayBuilder.toString());
  174.  
  175. Gender gender = parseGender(chars[14]);
  176.  
  177. return new IDCertNoValidateResult(gender, birthday);
  178. }
  179.  
  180. private static void checkAreaCode(char[] chars, int startIndex, int length)
  181. throws InvalidParameterException {
  182. String areaCode = new String(chars, startIndex, 2);
  183. if (!ZONE_NUMBER.containsKey(areaCode)) {
  184. String msg = "parse area code failed: " + areaCode;
  185. LOGGER.error(msg);
  186. Map<String, String> errorDesc = new HashMap<>();
  187. errorDesc.put(INVALID_FIELD_NAME_AREA_CODE, msg);
  188. throw new InvalidParameterException(errorDesc);
  189. }
  190. }
  191.  
  192. private static Date parseBirthday(String birthdayStr) throws InvalidParameterException {
  193. Date birthday = null;
  194. try {
  195. birthday = DATE_FORMAT.parse(birthdayStr);
  196. } catch (ParseException e) {
  197. String msg = "parse birthday failed: " + birthdayStr;
  198. LOGGER.error(msg);
  199. Map<String, String> errorDesc = new HashMap<>();
  200. errorDesc.put(INVALID_FIELD_NAME_BIRTHDAY, msg);
  201. throw new InvalidParameterException(errorDesc);
  202. }
  203. return birthday;
  204. }
  205.  
  206. private static Gender parseGender(char genderChar) throws InvalidParameterException {
  207. if ((genderChar < '0') || (genderChar > '9')) {
  208. String msg = "parse gender failed: " + genderChar;
  209. LOGGER.error(msg);
  210. Map<String, String> errorDesc = new HashMap<>();
  211. errorDesc.put(INVALID_FIELD_NAME_GENDER, msg);
  212. throw new InvalidParameterException(errorDesc);
  213. }
  214.  
  215. if (((genderChar - '0') & 1) == 0) {
  216. return Gender.F;
  217. } else {
  218. return Gender.M;
  219. }
  220. }
  221.  
  222. private static void validateCheckChar(char[] chars) throws InvalidParameterException {
  223. char computedCheckChar = computeCheckChar(chars, 0, 17);
  224. char targetCheckChar = chars[17];
  225. if (computedCheckChar != targetCheckChar) {
  226. String msg = "validate check char failed: " + targetCheckChar;
  227. LOGGER.error(msg);
  228. Map<String, String> errorDesc = new HashMap<>();
  229. errorDesc.put(INVALID_FIELD_NAME_CHECK_CHAR, msg);
  230. throw new InvalidParameterException(errorDesc);
  231. }
  232. }
  233.  
  234. private static char computeCheckChar(char[] chars, int startIndex, int length) {
  235. int checkSum = 0;
  236. for (int i = 0; i < length; i++) {
  237. char c = chars[startIndex + i];
  238. checkSum += (c - '0') * POWER_LIST[i];
  239. }
  240.  
  241. int checkCharIndex = checkSum % 11;
  242. char checkChar = PARITYBIT[checkCharIndex];
  243. return checkChar;
  244. }
  245. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement