package com.basic.security.utils; import java.text.SimpleDateFormat; import java.util.Date; public class CheckIdCard { private final static String BIRTH_DATE_FORMAT = "yyyyMMdd"; private final static Date MINIMAL_BIRTH_DATE = new Date(-2209017600000L); private final static int NEW_CARD_NUMBER_LENGTH = 18; private final static int OLD_CARD_NUMBER_LENGTH = 15; private final static char[] VERIFY_CODE = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'}; private final static int[] VERIFY_CODE_WEIGHT = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; private String cardNumber; private Boolean cacheValidateResult = null; private Date cacheBirthDate = null; public CheckIdCard(String cardNumber) { if (null != cardNumber) { cardNumber = cardNumber.trim().toUpperCase(); if (OLD_CARD_NUMBER_LENGTH == cardNumber.length()) { cardNumber = contertToNewCardNumber(cardNumber); } } this.cardNumber = cardNumber; } private static char calculateVerifyCode(CharSequence cardNumber) { int sum = 0; for (int i = 0; i < NEW_CARD_NUMBER_LENGTH - 1; i++) { char ch = cardNumber.charAt(i); sum += (ch - '0') * VERIFY_CODE_WEIGHT[i]; } return VERIFY_CODE[sum % 11]; } private static String contertToNewCardNumber(String oldCardNumber) { StringBuilder buf = new StringBuilder(NEW_CARD_NUMBER_LENGTH); buf.append(oldCardNumber.substring(0, 6)); buf.append("19"); buf.append(oldCardNumber.substring(6)); buf.append(CheckIdCard.calculateVerifyCode(buf)); return buf.toString(); } public boolean validate() { if (null == cacheValidateResult) { boolean result = true; result = result && (null != cardNumber); result = result && NEW_CARD_NUMBER_LENGTH == cardNumber.length(); for (int i = 0; result && i < NEW_CARD_NUMBER_LENGTH - 1; i++) { char ch = cardNumber.charAt(i); result = result && ch >= '0' && ch <= '9'; } result = result && (calculateVerifyCode(cardNumber) == cardNumber .charAt(NEW_CARD_NUMBER_LENGTH - 1)); try { Date birthDate = this.getBirthDate(); result = result && null != birthDate; result = result && birthDate.before(new Date()); result = result && birthDate.after(MINIMAL_BIRTH_DATE); String birthdayPart = this.getBirthDayPart(); String realBirthdayPart = this.createBirthDateParser().format( birthDate); result = result && (birthdayPart.equals(realBirthdayPart)); } catch (Exception e) { result = false; } cacheValidateResult = Boolean.valueOf(result); } return cacheValidateResult; } public String getCardNumber() { return cardNumber; } public String getAddressCode() { this.checkIfValid(); return this.cardNumber.substring(0, 6); } public Date getBirthDate() { if (null == this.cacheBirthDate) { try { this.cacheBirthDate = this.createBirthDateParser().parse( this.getBirthDayPart()); } catch (Exception e) { throw new RuntimeException("身份证的出生日期无效"); } } return new Date(this.cacheBirthDate.getTime()); } public boolean isMale() { return 1 == this.getGenderCode(); } public boolean isFemal() { return false == this.isMale(); } private int getGenderCode() { this.checkIfValid(); char genderCode = this.cardNumber.charAt(NEW_CARD_NUMBER_LENGTH - 2); return (genderCode - '0' & 0x1); } private String getBirthDayPart() { return this.cardNumber.substring(6, 14); } private SimpleDateFormat createBirthDateParser() { return new SimpleDateFormat(BIRTH_DATE_FORMAT); } private void checkIfValid() { if (false == this.validate()) { throw new RuntimeException("身份证号码不正确!"); } } }