一个居民身份证的工具类 (GB11643-1999)

package com.hitb.stat.util;



import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.regex.Pattern;



import com.hitb.exception.HITBRuntimeException;



/**

 * 身份证号码工具类

 * 

 * 包括校验验证码、关联出生日期校验

 * 

 * 同时适用于 15位、18位身份证

 * 

 * @author GF

 *

 */

public class IDNumber {

	

	/**

	 * 15位身份证号码需要添加19年份的前缀

	 */

	private final static char [] YEAR_PREFIX_19 = "19".toCharArray();

	/**

	 * 将15位的身份证号码转为18位

	 * 

	 * @param psID

	 *            15位身份证

	 * @return 转化后的号码

	 */

	public static String convertToID_18(String psID) {

		

		if( HITBUtils.isEmptyString(psID))

			throw new HITBRuntimeException("身份证号码为空!");

		

		if(!MASK_CODE_ID15.matcher(psID).matches()){

			throw new HITBRuntimeException("给定 15位身份证号码不合法!");

		}

		

		String sID_17 = new StringBuffer(psID).insert(6, YEAR_PREFIX_19).toString();

	

		return sID_17 + createVerifyCode(sID_17);

	}

	

	/**

	 * 18 位身份证号码验证正则表达式

	 */

	private static final Pattern MASK_CODE_ID18 = Pattern.compile("//d{17}[//dxX]");

	

	/**

	 * 15 位身份证号码验证正则表达式

	 */

	private static final Pattern MASK_CODE_ID15 = Pattern.compile("//d{15}");

	

	/**

	 * @param psID

	 * @return 如果18位或18位身份证号码中的验证码正确,返回true

	 */

	public static boolean verifyID(String psID){

		

		if(HITBUtils.isEmptyString(psID))

			return false;

		

		if(psID.length() == 18){

			if(!MASK_CODE_ID18.matcher(psID).matches()){

				return false;

			}

			return createVerifyCode(psID) == psID.toCharArray()[17];

		}

		

		if(psID.length() == 15){

			return MASK_CODE_ID15.matcher(psID).matches();

		}

		

		return false;

	}

	

	

	

	/**

	 * 出生日期格式

	 */

	private static final SimpleDateFormat BIRTHDAY_FORMAT = new SimpleDateFormat("yyyyMMdd");

	/**

	 * @param psID 15 位或 18位身份证号码

	 * @param pdBirthday 出生日期

	 * @return 如果出生日期与身份证编码相符,返回true,反之返回false

	 */

	public static boolean verifyIDByBirthday(String psID, Date pdBirthday){

		

		String sID = psID;

		

		// 身份证号码或日期为空

		if( HITBUtils.isEmptyString(sID) || pdBirthday == null){

			return false;

		}

		

		// 身份证号码无效、非法

		if(!verifyID(sID))

			return false;

		

		// 如果是15位身份证,转换为 18位

		if(sID.length() == 15)

			sID = convertToID_18(sID);

		

		return BIRTHDAY_FORMAT.format(pdBirthday).equals(sID.substring(6,14));

	}

	

	/**

	 * @param psID 15 位或 18位身份证号码

	 * @param piGenderCode 性别代码 ,1-男  2-女

	 * @return 如果性别与身份证中的性别编码相符,返回 true,反之返回false

	 */

	public static boolean verifyIDByGender(String psID, int piGenderCode){

		String sID = psID;

		

		// 性别代码错误

		if(piGenderCode != 1 && piGenderCode!= 2){

			return false;

		}

		

		// 身份证号码无效、非法

		if(!verifyID(sID))

			return false;

		

		// 如果是15位身份证,转换为 18位

		if(sID.length() == 15)

			sID = convertToID_18(sID);

		

		return ((Integer.valueOf(sID.substring(17,18)).intValue() % 2) + piGenderCode) == 2;

	}

	

	

	

	/**

	 * 具体的验证码算法见 需求资料  GB11643-1999.pdf

	 * @param psID 身份证号码 (不少于 17位,可用没有18位验证码)

	 * @return 返回给定身份证号码的验证代码

	 */

	private static char createVerifyCode(String psID){

		

		if(HITBUtils.isEmptyString(psID) || psID.length()< 17 )

			throw new HITBRuntimeException("身份证号码不完整,无法生成验证码!(不能少于17位)");

		

		char arycID[]=psID.toCharArray();

		

        int iSum = 0;

        int aryiW[]={7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};

        

        // 验证码数组(标准)

        char arycVerCodes[] = new char[]{'1','0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};

        int i;

        for(i=0;i<17;i++){

        	iSum += (int)(arycID[i]-'0') * aryiW[i];

        }

        // 模11取余数

        int iIndex = iSum % 11;

        

        // 检查验证码是否正确

        return arycVerCodes[iIndex];

	}

	

	

	



	/**

	 * @param args

	 * @throws ParseException 

	 */

	public static void main(String[] args) throws ParseException {

		

		String sID_18 = "110224198209211129";

		

		String sID_15 = "110224820921112";

		

		Date dBirthday = BIRTHDAY_FORMAT.parse("19730526");

		

		System.out.println("校验18位身份证号码: " + sID_18 + " " + verifyID(sID_18));

		

		System.out.println("校验15位身份证号码: " + sID_15 + " " + verifyID(sID_15));

		

		System.out.println("升级15位身份证号码: " + sID_15 + " " + convertToID_18(sID_15));

		

		System.out.println("校验18位身份证号码出生日期: " + sID_18 + " " + verifyIDByBirthday(sID_18,dBirthday));

		

		System.out.println("校验15位身份证号码出生日期: " + sID_15 + " " + verifyIDByBirthday(sID_15,dBirthday));

		

		System.out.println("校验15位身份证号码性别: " + sID_15 + " " + verifyIDByGender(sID_15,1));

		

		System.out.println("校验18位身份证号码性别: " + sID_18 + " " + verifyIDByGender(sID_15,2));

		

	}

	

	/*

	  	校验18位身份证号码: 110224198209211129 true

		校验15位身份证号码: 110224820921112 true

		升级15位身份证号码: 110224820921112 110224198209211129

		校验18位身份证号码出生日期: 110224198209211129 false

		校验15位身份证号码出生日期: 110224820921112 false

		校验15位身份证号码性别: 110224820921112 true

		校验18位身份证号码性别: 110224198209211129 fals

	 * 

	 */

	

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值