Java身份证号码验证

今天对身份证号码规则进行了简单的了解,然后试着写了一下身份证号码的验证,在此做一下记录,以备以后使用:

代码如下:

import java.util.Hashtable;
import java.util.regex.Pattern;

/**
 * 身份证号码,可以解析身份证号码的各个字段,以及验证身份证号码是否有效<br>
 * 身份证号码构成:6位地址编码+8位生日+3位顺序码+1位校验码
 * 
 */
public class ValidateIDCard {

	/**
	 * 身份证号验证(18位新身份证号)
	 * @param validateStr 身份证号码
	 * @return  true:合法 | false:非法
	 */
	@SuppressWarnings("unchecked")
	public static boolean isValidIDCardNum(String validateStr){
		if(validateStr.length()!=18){
			return false;
		}
		String regex = "[0-9]{17}[0-9|xX]$";
		Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
		if(!pattern.matcher(validateStr).matches()){//前17位数字,第18位数字或字母X
			return false;
		}
		Hashtable areacodeHashtable = new Hashtable();
		areacodeHashtable.put("11", "北京");     
		areacodeHashtable.put("12", "天津");     
		areacodeHashtable.put("13", "河北");     
		areacodeHashtable.put("14", "山西");     
		areacodeHashtable.put("15", "内蒙古");   
		areacodeHashtable.put("21", "辽宁");     
		areacodeHashtable.put("22", "吉林");     
		areacodeHashtable.put("23", "黑龙江");   
		areacodeHashtable.put("31", "上海");     
		areacodeHashtable.put("32", "江苏");     
		areacodeHashtable.put("33", "浙江");     
		areacodeHashtable.put("34", "安徽");     
		areacodeHashtable.put("35", "福建");     
		areacodeHashtable.put("36", "江西");     
		areacodeHashtable.put("37", "山东");     
		areacodeHashtable.put("41", "河南");     
		areacodeHashtable.put("42", "湖北");     
		areacodeHashtable.put("43", "湖南");     
		areacodeHashtable.put("44", "广东");     
		areacodeHashtable.put("45", "广西");     
		areacodeHashtable.put("46", "海南");     
		areacodeHashtable.put("50", "重庆");     
		areacodeHashtable.put("51", "四川");     
		areacodeHashtable.put("52", "贵州");     
		areacodeHashtable.put("53", "云南");     
		areacodeHashtable.put("54", "西藏");     
		areacodeHashtable.put("61", "陕西");     
		areacodeHashtable.put("62", "甘肃");     
		areacodeHashtable.put("63", "青海");     
		areacodeHashtable.put("64", "宁夏");     
		areacodeHashtable.put("65", "新疆");     
		areacodeHashtable.put("71", "台湾");     
		areacodeHashtable.put("81", "香港");     
		areacodeHashtable.put("82", "澳门");     
		areacodeHashtable.put("91", "国外");
		if(areacodeHashtable.get(validateStr.substring(0,2))==null){
			return false;
		}
		String birthdate = validateStr.substring(6, 14);//获取生日
		int birthyear = Integer.parseInt(birthdate.substring(0, 4));//出生年份
		int curyear = java.util.Calendar.getInstance().get(java.util.Calendar.YEAR);//当前时间年份
		if(birthyear>=curyear || birthyear <1900){//不在1900年与当前时间之间
			return false;
		}
		String dateRegex = "^((\\d{2}(([02468][048])|([13579][26]))[\\/\\/\\s]?((((0 ?[13578])|(1[02]))[\\/\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\/\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\/\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\/\\/\\s]?((((0?[13578])|(1[02]))[\\/\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\/\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\/\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))";
		if(!Pattern.compile(regex, Pattern.CASE_INSENSITIVE).matches(dateRegex, birthdate)){//出生年月日不合法
			return false;
		}
		/**
		 * 计算校验码(第十八位数):
		 * 十七位数字本体码加权求和公式 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;
		 * 计算模 Y = mod(S, 11)
		 * 通过模Y得到对应的校验码: 0 1 2 3 4 5 6 7 8 9 10 校验码: 1 0 X 9 8 7 6 5 4 3 2
		 */
		final String[] LASTCODE = { "1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2" };// 18位身份证中最后一位校验码
		final int[] WEIGHT = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };// 18位身份证中,前17位数字各个数字的生成校验码时的权值
		String tempLastCode = "";//临时记录身份证号码最后一位
		int sum = 0;//前17位号码与对应权重值相乘总和
		for(int i=0; i<17; i++){
			sum += ((int)(validateStr.charAt(i)-'0'))*WEIGHT[i];
		}
		tempLastCode = LASTCODE[sum%11];//实际最后一位号码
		System.out.println(tempLastCode);
		if(validateStr.substring(17).equals(tempLastCode)){//最后一位符合
			return true;
		}else{
			return false;
		}
	}
}

如有不足之处,请批评指正!

转载于:https://my.oschina.net/4k9LCGA/blog/78156

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值