【转】身份证号和银行卡号校验码的生成规则和算法

【转自 https://blog.csdn.net/u010267906/article/details/75257341?utm_source=blogxgwz1】

一、身份证号校验码生成规则和算法(只针对18位身份证号码):

1、公民身份证号码是特征组合码,由十七位数字本体码和一位校验码组成,排列顺序从左到右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位校验码。

地址码:表示编码对象常住户口所在县(市、旗、区)的行政区域划分代码,按GB/T2260的规定执行。

出生日期码:表示编码对象出生的年、月、日,按GB/T7408的规定执行,年、月、日代码之间不用分隔符。
顺序码:表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性。

2、校验码计算步骤:

(1)十七位数字本体码加权求和公式
  S = Sum(Ai * Wi), i = 0, ... , 16 ,先对前17位数字的权求和
  Ai:表示第i位置上的身份证号码数字值(0~9)
  Wi:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 (表示第i位置上的加权因子)

(说明:加权因子是计算公式是硬性规定的,公式为:mod(2^(18-n),11))


(2)计算模
  Y = mod(S, 11)

(3)根据模,查找得到对应的校验码
  Y:             0  1  2  3  4  5  6  7  8  9  10
  校验码:    1  0  X  9  8  7  6  5  4  3   2

3、Java计算校验码算法:

public class Id18 {
    int[] weight={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};    //十七位数字本体码权重
    char[] validate={ '1','0','X','9','8','7','6','5','4','3','2'};    //mod11,对应校验码字符值    
    
    public char getValidateCode(String id17){
        int sum=0;
        int mode=0;
        for(int i=0;i<id17.length();i++){
            sum=sum+Integer.parseInt(String.valueOf(id17.charAt(i)))*weight[i];
        }
        mode=sum%11;
        return validate[mode];
    }
    
    public static void main(String[] args){
        Id18 test=new Id18();
        System.out.println("该身份证验证码:"+test.getValidateCode("14230219700101101"));    //该身份证校验码:3
    }
}

二、银行卡号码校验码生成规则和算法

1、 Luhn是著名的校验和算法也叫模10算法,主要应用于解决银行卡号,社保号等重要信息传输出错问题。

算法原理:校验和类型的算法,一般是ID+校验号,校验号和ID号的每位相关,如果出错,通过某种运算能检测出这种改动。以数字“7992739871”为例,计算其校验位:
从校验位开始,从右往左,偶数位乘2(例如,7*2=14),然后将两位数字的个位与十位相加(例如,10:1+0=1,14:1+4=5);
把得到的数字加在一起(本例中得到67);
将数字的和取模10(本例中得到7),再用10去减(本例中得到3),得到校验位。
2、Java实现银行卡号码校验码的生成算法:

   /**
     * 从不含校验位的银行卡卡号采用 Luhm 校验算法获得校验位
     * 该校验的过程: 
     * 1、从卡号最后一位数字开始,逆向将奇数位(1、3、5等等)相加。 
     * 2、从卡号最后一位数字开始,逆向将偶数位数字,先乘以2(如果乘积为两位数,则将其减去9),再求和。 
     * 3、将奇数位总和加上偶数位总和,结果应该可以被10整除。
     */
    public static char getBankCardCheckCode(String nonCheckCodeCardId){  
    if(nonCheckCodeCardId == null || nonCheckCodeCardId.trim().length() == 0  
    || !nonCheckCodeCardId.matches("\\d+")||nonCheckCodeCardId.trim().length()<15
    ||nonCheckCodeCardId.trim().length()>18) {  
        //如果传的数据不合法返回N  
        System.out.println("银行卡号不合法!");
        return 'N';
    }  
    char[] chs = nonCheckCodeCardId.trim().toCharArray();  
    int luhmSum = 0; 
    // 执行luh算法
      for(int i = chs.length - 1, j = 0; i >= 0; i--, j++) {  
            int k = chs[i] - '0';  
            if(j % 2 == 0) {  //偶数位处理
               k *= 2;  
               k = k / 10 + k % 10;  
            }  
            luhmSum += k;             
         }  
         return (luhmSum % 10 == 0) ? '0' : (char)((10 - luhmSum % 10) + '0');  
    }  
---------------------
作者:西决987654
来源:CSDN
原文:https://blog.csdn.net/u010267906/article/details/75257341
版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自www.cnblogs.com/simplezhuo/p/9838688.html