java字符串应用之18位身份证格式验证

    公民身份号码是特征组合码,由17位数字本体码和1位数字校验码组成。排列顺序从左至右依次为:6位数字地址码、8位数字出生日期码,3位数字顺序码和1位数字校验码。
    地址码:表示编码对象常住户口所在县(市、旗、区)的行政区划代码,按 GB/T 2260的规定执行。
    出生日期码:表示编码对象的出生年、月、日,按GB/T 7408的规定执行。
    顺序码:表示在同一地址码所标识的区域范围内,对同年,同月,同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性。
    校验码:校验码采用ISO 7064: 1983, MOD 11-2校验码系统。

一、关键技术点
    1、求验证码的方法是:
        对前17位数字本体码加权求和,公式为:S = Sum(Ai * Wi),i = 0,......,16,其中Ai表示第i位置上的身份证号码数字值,Wi表示第i位置上的加权因子,加权因子的值从0到16位分别为7、9、10、5、8、4、2、1、6、3、7、9、10、5、8、4、2。
        然后对S取模,公式为:Y = mod(S,11)。
        然后通过模Y得到对应的校验码。对应关系为<0,1>,<1,0>,<2,X>,<3,9>,<4,8>,<5,7>,<6,6>,<7,5>,<8,4>,<9,3>,<10,2>。关系中前者为Y值,后者为对应的校验码。
       
二、演示实例

 

/**
 * 文件名IDCard.java
 
*/

package  book.oo.String;

public   class  IDCard  {
    
private static final int[] weight = new int[] 7910584216,
            
3791058421 }
// 加权因子
    private static final int[] checkDigit = new int[] 10'X'9876,
            
5432, }
;
    
    
public IDCard() {
    }

    
    
/**
     * 计算18位身份证的校验码
     
*/

    
private String getCheckDigit(String eighteenCardId) {
        
int remaining = 0;
        
//先取得18位身份证的17位本体码
        if(eighteenCardId.length() == 18{
            eighteenCardId 
= eighteenCardId.substring(017);
        }

        
//根据公式对本体码进行加权求和
        if(eighteenCardId.length() == 17{
            
int sum = 0;
            
int[] a = new int[17];
            
//先对前17位数字的权求和
            for(int i = 0; i < 17; i++{
                String k 
= eighteenCardId.substring(i, i+1);
                a[i] 
= Integer.parseInt(k);
            }

            
for(int i = 0; i < 17; i++{
                sum 
= sum + weight[i] * a[i];
            }

            
//再与11取模
            remaining = sum % 11;
        }

        
//返回校验码
        return remaining == 2 ? "X" : String.valueOf(checkDigit[remaining]);
    }

    
    
/**
     * 将15位身份证号码升级为18位身份证号码
     
*/

    
private String update2eighteen(String fifteenCardID) {
        
//15位身份证上的生日的年份没有加19,要加上
        String eighteenCardID = fifteenCardID.substring(0,6);
        eighteenCardID 
= eighteenCardID + "19";
        eighteenCardID 
= eighteenCardID + fifteenCardID.substring(6,15);
        eighteenCardID 
= eighteenCardID + this.getCheckDigit(eighteenCardID);
        
return eighteenCardID;
    }

    
    
/**
     * 验证身份证是否符合格式
     
*/

    
public boolean verify(String idcard) {
        
if(idcard.length() == 15{
            idcard 
= this.update2eighteen(idcard);
        }

        
if(idcard.length() != 18{
            
return false;
        }

        
//获取身份证上的最后一位,它是校验码
        String checkDigit = idcard.substring(17,18);
        
//比较获取的校验码与生成的校验码是否相等
        if (checkDigit.equals(this.getCheckDigit(idcard))) {
            
return true;
        }

        
return false;
    }

    
    
public static void main(String[] args) {
        IDCard test 
= new IDCard();
        String idCardStr 
= "110105194912310025";
        System.out.println(
"身份证:" + idCardStr + "验证合格?" + test.verify(idCardStr));
        idCardStr 
= "632826198011290019";
        System.out.println(
"身份证:" + idCardStr + "验证合格?" + test.verify(idCardStr));
    }


}

 输出结果:

身份证:110105194912310025验证合格?false
身份证:632826198011290019验证合格?true

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值