Java身份证号码验证器

#java #Validator
 import java.text.ParseException;
 
 /**
  * 身份证号码验证   

  * 1、号码的结构   

  * 公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为:六位数字地址码,   

  * 八位数字出生日期码,三位数字顺序码和一位数字校验码。   

  * 2、地址码(前六位数)   

  * 表示编码对象常住户口所在县(市、旗、区)的行政区划代码,按GB/T2260的规定执行。   

  * 3、出生日期码(第七位至十四位)   

  * 表示编码对象出生的年、月、日,按GB/T7408的规定执行,年、月、日代码之间不用分隔符。   

  * 4、顺序码(第十五位至十七位)   

  * 表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,   

  * 顺序码的奇数分配给男性,偶数分配给女性。   

  * 5、校验码(第十八位数)   

  * (1)十七位数字本体码加权求和公式 S = Sum(Ai * Wi), i = 0, , 16 ,先对前17位数字的权求和   

  * Ai:表示第i位置上的身份证号码数字值 Wi:表示第i位置上的加权因子 Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4   

  * 2 (2)计算模 Y = mod(S, 11) (3)通过模得到对应的校验码 Y: 0 1 2 3 4 5 6 7 8 9 10 校验码: 1 0   

  * X 9 8 7 6 5 4 3 2   

  * 
  * @author Geln Yang
  * 
  */
 public class IdentityCardUtil {
 
 	private static final String IDENTITY_NO_REGEX = "([\\d]{15})|([\\d]{17}(\\d|[xX]))";
 	private static final String DATE_REGEX = "^((\\d{2}(([02468][048])|([13579][26]))((((0?[13578])|(1[02]))((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))((0?[1-9])|([1-2][0-9])|(30)))|(0?2((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))((((0?[13578])|(1[02]))((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))((0?[1-9])|([1-2][0-9])|(30)))|(0?2((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[0-9])|([1-2][0-3]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$";
 	private static char[] VALIDATE_CODE_ARR = { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' };
 	private static int[] POWSER_ARR = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
 	private static int[] AREA_CODE_ARR = new int[100];
 
 	static {
 		for (int i = 0; i < 100; i++) {
 			AREA_CODE_ARR[i] = 0;
 		}
 		AREA_CODE_ARR[11] = 1;// 北京
 		AREA_CODE_ARR[12] = 1;// 天津
 		AREA_CODE_ARR[13] = 1;// 河北
 		AREA_CODE_ARR[14] = 1;// 山西
 		AREA_CODE_ARR[15] = 1;// 内蒙古
 		AREA_CODE_ARR[21] = 1;// 辽宁
 		AREA_CODE_ARR[22] = 1;// 吉林
 		AREA_CODE_ARR[23] = 1;// 黑龙江
 		AREA_CODE_ARR[31] = 1;// 上海
 		AREA_CODE_ARR[32] = 1;// 江苏
 		AREA_CODE_ARR[33] = 1;// 浙江
 		AREA_CODE_ARR[34] = 1;// 安徽
 		AREA_CODE_ARR[35] = 1;// 福建
 		AREA_CODE_ARR[36] = 1;// 江西
 		AREA_CODE_ARR[37] = 1;// 山东
 		AREA_CODE_ARR[41] = 1;// 河南
 		AREA_CODE_ARR[42] = 1;// 湖北
 		AREA_CODE_ARR[43] = 1;// 湖南
 		AREA_CODE_ARR[44] = 1;// 广东
 		AREA_CODE_ARR[45] = 1;// 广西
 		AREA_CODE_ARR[46] = 1;// 海南
 		AREA_CODE_ARR[50] = 1;// 重庆
 		AREA_CODE_ARR[51] = 1;// 四川
 		AREA_CODE_ARR[52] = 1;// 贵州
 		AREA_CODE_ARR[53] = 1;// 云南
 		AREA_CODE_ARR[54] = 1;// 西藏
 		AREA_CODE_ARR[61] = 1;// 陕西
 		AREA_CODE_ARR[62] = 1;// 甘肃
 		AREA_CODE_ARR[63] = 1;// 青海
 		AREA_CODE_ARR[64] = 1;// 宁夏
 		AREA_CODE_ARR[65] = 1;// 新疆
 		AREA_CODE_ARR[71] = 1;// 台湾
 		AREA_CODE_ARR[81] = 1;// 香港
 		AREA_CODE_ARR[82] = 1;// 澳门
 		AREA_CODE_ARR[91] = 1;// 国外
 	}
 
 	/**
 	 * 功能:身份证的有效验证
 	 * 
 	 * @param identityNo
 	 * @return true/false
 	 */
 	public static boolean validate(String identityNo) {
 		if (identityNo == null) {
 			return false;
 		}
 		if (!identityNo.matches(IDENTITY_NO_REGEX)) {
 			return false;
 		}
 		if (AREA_CODE_ARR[Integer.parseInt(identityNo.substring(0, 2))] == 0) {
 			return false;
 		}
 		String date = identityNo.length() == 15 ? "19" + identityNo.substring(6, 12) : identityNo.substring(6, 14);
 		if (!date.matches(DATE_REGEX)) {
 			return false;
 		}
 		if (identityNo.length() == 15) {
 			return true;
 		}
 		int checksum = 0;
 		for (int i = 0; i < 17; i++) {
 			checksum = checksum + (identityNo.charAt(i) - 48) * POWSER_ARR[i];
 		}
 		char verifyCode = VALIDATE_CODE_ARR[checksum % 11];
 		if (identityNo.charAt(17) != verifyCode) {
 			return verifyCode == 'X' ? identityNo.charAt(17) == 'x' : false;
 		}
 		return true;
 	}
 
 	public static char calculateCheckNum(char[] out) {
 		int checksum = 0;
 		for (int i = 0; i < 17; i++) {
 			checksum = checksum + (out[i] - 48) * POWSER_ARR[i];
 		}
 		return VALIDATE_CODE_ARR[checksum % 11];
 	}
 
 	public static void main(String[] args) throws ParseException {
 		testValid("210102820826411");
 		testValid("21010219820826411");
 		testValid("210102198208264114");
 		testValid("500113198606245216");
 	}
 
 	private static void testValid(String c) {
 		System.out.println(c + ":" + validate(c));
 	}
 
 }