新旧身份证合法性验证及验证算法

1.         中国公民身份证常识:

我国现行使用公民身份证号码有两种尊循两个国家标准,〖GB 11643-1989〗和〖GB 11643-1999〗。

GB 11643-1989〗中规定的是15位身份证号码:排列顺序从左至右依次为:六位数字地址码,六位数字出生日期码,三位数字顺序码,其中出生日期码不包含世纪数。

 

6行政区划分代码

6位出生日期

3位顺序

 

       GB 11643-1999〗中规定的是18位身份证号码:公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。

 

6位行政区划分代码

6位出生日期

3位顺序码

1位校验码

 

       行政区划分代码:表示编码对象常住户口所在县(市、旗、区)的行政区划代码。

       行政区划分代码国家标准GB T 2260-1999

       出生日期码:表示编码对象出生的年、月、日,其中年份用四位数字表示,年、月、日之间不用分隔符。

       顺序码:表示同一地址码所标识的区域范围内,对同年、同月、同日出生的人员编定的顺序号。顺序码的奇数分给男性,偶数分给女性。

    校验码:是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。

ISO 7064:1983.MOD 11-2校验码计算法

 

按照中华人民共和国国家标准GB11643-1999规定中华人民共和国公民身份号码校验码的计算方法即为ISO 7064:1983.MOD 11-2校验码计算法。

假设某一17位数字是

17位数字12345678901234567
加权因子2485109736124851097
  1. 计算17位数字各位数字与对应的加权因子的乘积的和S:1×2+2×4+3×8+4×5+5×10+6×9+7×7+8×3+9×6+0×1+1×2+2×4+3×8+4×5+5×10+6×9+7×7=492;
  2. 计算S÷11的余数T:492 mod 11=8;
  3. 计算(12-T)÷11的余数R,如果R=10,校验码为字母“X”;如果R≠10,校验码为数字“R”:(12-8)mod 11=4。

该17位数字的校验码就是4,聚合在一为123456789012345674

package id_card;

import string_util.StringUtil;

/**
 * 身份证号码验证小程序
 * @author Kevin
 * 2010-3-28
 */
public class IdCardUtil {
	/** 旧身份证号码位数(完全有数字组成) */
	public static final int OLD_IDCARD_LEN=15;
	/** 新身份证号码位数 */
	public static final int NEW_IDCARD_LEN=18;
	/** 存放位权值数组 */
	private static int[] wi=new int[17];
    /**最小行政区划分代码*/
    private final static int MINCODE = 110000;
    /**最大行政区划分代码*/
    private final static int MAXCODE = 820000;
    /** 求模参数 */
    private final static int MODE=11;
    /** 新身份证年份标记 */
    private final static String YEAR_FLAG="19";
    /**
     * 设置位权值
     */
    private static void setWiValue(){
    	for(int i=0;i<wi.length;i++){
    		int k=(int)Math.pow(2, (wi.length-i));
    		wi[i]=k%MODE;
    	}
    }
    /**
     * 依据新身份证号码前17为数字,得到最后一位验证码
     * @param checkString
     * @return
     */
    private static String getCheckCode(String checkString){
    	int sum=0;
    	setWiValue();//设置位权值
    	for(int i=0;i<checkString.length();i++){
    		int k=StringUtil.convertInteger(String.valueOf(checkString.charAt(i)))*wi[i];
    		sum+=k;
    	}
    	int num=(12-(sum%MODE))%MODE;
    	if(num==10){
    		return "X";
    	}else{
    		return String.valueOf(num);
    	}
    	
    }
    /**
     * 验证身份证号码行政区划分代码是否有效
     * @param idCard
     * @return
     */
    public static boolean isValidateCantonCode(String idCard) throws Exception{
    	String cantonCode=idCard.substring(0,6);
    	int code=StringUtil.convertInteger(cantonCode);
    	if(code>=MINCODE && code<=MAXCODE){
    		return true;
    	}
    	return false;
    }
    /**
     * 验证新身份证最后一位是否有效
     * @param lastLetter
     * @return
     */
	private static boolean isValidateLastCode(String lastCode){
		//是否是数字、'x'或'X'
		if(StringUtil.isCompleteNumberString(lastCode)||lastCode.equalsIgnoreCase("x")){
			return true;
		}
		return false;
	}
    /**
     * 验证身份证是否有效
     * @param idCard
     * @return
     */
    public static boolean isValidateIdCard(String idCard) throws Exception{
    	//验证是否是过有效字符串
    	if(!StringUtil.isValidateString(idCard)){
    		return false;
    	}
    	//去除前后空格
    	idCard=idCard.trim();
    	//验证身份证号码是不是15位或18位
    	if(idCard.length()!=OLD_IDCARD_LEN && idCard.length()!=NEW_IDCARD_LEN){
    		return false;
    	}
    	//验证身份证号码行政区划分代码是否有效
    	if(!isValidateCantonCode(idCard)){
    		return false;
    	}
    	//身份证生日号码
    	String birthday="";
    	
    	if(idCard.length()==OLD_IDCARD_LEN){
    		if(StringUtil.isCompleteNumberString(idCard)){
    			birthday=YEAR_FLAG+idCard.substring(6,12);
    		}
    	}else{
    		if(StringUtil.isCompleteNumberString(idCard.substring(0,17))){
    			if(isValidateLastCode(idCard.substring(17, idCard.length()))){
    				birthday=idCard.substring(6, 14);
    			}
    		}
    	}
    	//验证生日日期格式是否有效
		if(!StringUtil.isValidateDateString(birthday, "yyyyMMdd")){
			return false;
		}
		//验证新身份证最后一位是否有效
		if(idCard.length()==NEW_IDCARD_LEN){
			String lastCode=getCheckCode(idCard.substring(0,17));
			if(!(String.valueOf(idCard.charAt(17)).equalsIgnoreCase(lastCode))){
				return false;
			}
		}
		
    	return true;
    }
    /**
     * 将旧身份证号码转化为新身份证号码
     * @param code
     * @return
     * @throws Exception
     */
	public static String oldCard2newCarid(String oldIdCard) throws Exception{
		if(!StringUtil.isValidateString(oldIdCard)){
			return "";
		}
		oldIdCard=oldIdCard.trim();
		if(oldIdCard.length()!=OLD_IDCARD_LEN||!isValidateIdCard(oldIdCard)){
			return "";
		}
		oldIdCard=oldIdCard.substring(0,6)+YEAR_FLAG+oldIdCard.substring(6);
		oldIdCard=oldIdCard+getCheckCode(oldIdCard);
		return oldIdCard;
	}
	/**
	 * 测试
	 * @param args
	 * @throws Exception
	 */
	public static void main(String args[]) throws Exception{
		System.out.println(IdCardUtil.isValidateIdCard("000000000000000000"));
	}
}

 

package string_util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;


public final class StringUtil{
	/**
	 * 字符串数组合并
	 * @param stringAry 字符串数组
	 * @param joinToken 分隔符
	 * @return 合并后的字符串
	 */
	public static String join(String []stringAry,String joinToken){
		if(stringAry==null||stringAry.length<=0){
			return null;
		}
		if(joinToken==null||joinToken.equalsIgnoreCase("null")){
			joinToken="";
		}
		joinToken=joinToken.trim();
		StringBuffer sb=new StringBuffer();
		for(int i=0;i<stringAry.length;i++){
			if(i>0){
				sb.append(joinToken);
			}
			sb.append(stringAry[i]);
		}
		return sb.toString();
	}
	/**
	 * 将整数字符串转化为整数
	 * @param str 数字字符串
	 * @return 转化后的Int类型
	 * @throws NumberFormatException
	 */
	public static int convertInteger(String str) throws NumberFormatException{
		int number=0;
		if(!isValidateString(str)){
			return number;
		}
		str=str.trim();
		try {
			number=Integer.parseInt(str);
		} catch (NumberFormatException e) {
			throw e;
		}
		return number;
	}
	/**
	 * 将浮点数的字符串转化为浮点数
	 * @param str 要转化的字符串
	 * @return 转化后的浮点数
	 * @throws NumberFormatException
	 */
	public static float convertFloat(String str)throws NumberFormatException{
		float number=0.0f;
		if(!isValidateString(str)){
			return number;
		}
		str=str.trim();
		try {
			number=Float.parseFloat(str);
		} catch (NumberFormatException e) {
			throw e;
		}
		return number;
	}
	/**
	 * 将双精度浮点数的字符串转化为双精度浮点数
	 * @param str 要转化的字符串
	 * @return 转化后的值
	 * @throws NumberFormatException
	 */
	public static double convertDouble(String str)throws NumberFormatException{
		double number=0.0;
		if(!isValidateString(str)){
			return number;
		}
		str=str.trim();
		try {
			number=Double.parseDouble(str);
		} catch (NumberFormatException e) {
			throw e;
		}
		return number;
	}
	/**
	 * 验证字符串合法性(即该字符串不可以为null)
	 * 该方法不除去字符串中空格
	 * @param str String
	 * @return 如果为空就返回""
	 */
	public static String CheckString(String str){
		if(str==null||str.equalsIgnoreCase("null")){
			return "";
		}
		/**
		 * 除去前后的空格
		 */
		return str.trim();
	}
	/**
	 * 验证字符串合法性(该字符串可以为null)
	 * 该方法不除去字符串中空格
	 * @param str String
	 * @return 如果为空就返回""
	 */
	public static String ValidateString(String str){
		if(str==null){
			return "";
		}
		/**
		 * 除去前后的空格
		 */
		return str.trim();
	}
	/**
	 * 验证是否是个有效字符串
	 * @param str
	 * @return
	 */
	public static boolean isValidateString(String str){
		if(str==null){
			return false;
		}
		if(str.trim().equals("")){
			return false;
		}
		if(str.equalsIgnoreCase("null")){
			return false;
		}
		return true;
	}
	/**
	 * 从当前字符串中某个字符开始截取字符串
	 * @param str String
	 * @param singleChar String字符标记
	 * @param front boolean 如果值为true表式截取标记字符前面的字符,反之相反
	 * @return 截取后字符串
	 */
	public static String cutString(String str,String singleChar,boolean front){
		if(!isValidateString(str)){
			return "";
		}
		if(!isValidateString(singleChar)){
			return "";
		}
		str=str.trim();
		singleChar=singleChar.trim();
		if(str.contains(singleChar)){
			int index=str.indexOf(singleChar);
			if(front){
				return str.substring(0,index);
			}else{
				return str.substring(index+1,str.length());
			}
		}else{
			return str;
		}
	}
	/**
	 * 将数据库中取出以字符串形式表示的日期
	 * 转化为:1999-09-09日期格式形式
	 * @param dbStr String
	 * @return  String 转化后的字符串
	 */
	public static String toDateString(String dbStr){
		
		if(!isValidateString(dbStr)){
			return "";
		}
		dbStr=dbStr.trim();
		return dbStr.substring(0,10);
	}
	/**
	 * 将字符串一个字母转换为大写
	 * @param name
	 * @return
	 */
	public static String toUpperCaseFirstLetter(String name){
		if(!isValidateString(name)){
			return "";
		}
		name=name.trim();
		if(name.length()>0){
			return name.substring(0,1).toUpperCase()+name.substring(1);
		}
		return "";
	}
	/**
	 * 将JavaBean属性名转化为其set和get方法名称
	 * 其转化规则如下:(1)属性名的第二个字母若为大写则不用将首字母转换为大写
	 * @param prppertyName
	 * @return
	 */
	public static String toJavaBeanPropertyForSetOrGetMethodName(String propertyName){
		if(!isValidateString(propertyName)){
			return "";
		}
		propertyName=propertyName.trim();
		if(propertyName.length()<=1){
			return propertyName.toUpperCase();
		}else{
			char secondLetter=propertyName.charAt(1);
			if(secondLetter>='A'&& secondLetter<='Z'){
				return propertyName;
			}else{
				return toUpperCaseFirstLetter(propertyName);
			}
		}
	}
	/**
	 * 将日期字符串转换为日期对象
	 * @param dateString
	 * @return
	 * @throws ParseException
	 */
	public static Date toStringForDate(String dateString) throws Exception{
		Date date=null;
		if(!isValidateString(dateString)){
			throw new Exception("非日期格式字符串");
		}
		dateString=dateString.trim();
		DateFormat format=DateFormat.getDateInstance();
		
		try {
			date=format.parse(dateString);
		} catch (ParseException e) {
			throw e;
		}
		return date;
	}
	/**
	 * 验证字符串是不是完全有数字和小数点组成
	 * 此方法还不可以验证16进制和八进制的数据
	 * @param number
	 * @return
	 */
	public static boolean isNumberString(String number){
		
		if(!isValidateString(number)){
			return false;
		}
		number=number.trim();
		char[] nums=number.toCharArray();
		for(int i=0;i<nums.length;i++){
			if((nums[i]>='0'&& nums[i]<='9')||(nums[i]=='.')){
				continue;
			}else{
				return false;
			}
		}
		return true;
	}
	/**
	 * 验证字符串是不是完全有数字组成
	 * @param number
	 * @return
	 */
	public static boolean isCompleteNumberString(String number){
		
		if(!isValidateString(number)){
			return false;
		}
		number=number.trim();
		char[] nums=number.toCharArray();
		for(int i=0;i<nums.length;i++){
			if((nums[i]<'0'|| nums[i]>'9')){
				return false;
			}
		}
		return true;
	}
	/**
	 * 验证日期格式字符串是否和指定样式匹配
	 * @param date 
	 * @param style 指定样式
	 * @return
	 * @throws Exception
	 */
	public static boolean isValidateDateString(String dateStr,String style) throws Exception{
		if(!isValidateString(style)){
			return false;
		}
		if(!isValidateString(dateStr)){
			return false;
		}
		Date date=null;
		try{
		SimpleDateFormat sdf=new SimpleDateFormat(style);
		date =sdf.parse(dateStr);
		}catch(Exception e){
			throw e;
		}
		if(date==null){
			return false;
		}
		return true;
	}
	/**
	 * 测试方法
	 * @param args
	 * @throws Exception 
	 */
	public static void main(String args[]) throws Exception{
//		System.out.println(StringUtil.toJavaBeanPropertyForSetOrGetMethodName("aBc"));
		if(StringUtil.isValidateDateString("19860912","yyyyMMdd")){
			System.out.println("yes");
		}else{
			System.out.println("no");
		}
	}
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值