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
*
*/
}
一个居民身份证的工具类 (GB11643-1999)
最新推荐文章于 2024-01-12 18:24:00 发布