18 位身份证号码校验算法

因项目需要,在绑定银行卡的时候,需要校验身份证号码是否合法,于是去 Google 了一下,现总结如下

18 身份证号码的结构

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

地址码

表示编码对象常住户口所在县 (市、旗、区) 的行政区划代码
最新的行政区划代码 在这里

出生日期码

表示编码对象出生的年、月、日,年、月、日代码之间不使用分隔符

顺序码

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

校验码计算步骤

第一步:对十七位数字本体码加权求和得到 Sum

第二步:对 Sum 取模 11 得到 Y

第四步:根据模 Y ,查找得到对应的校验码

简易代码如下

public class IdCard {

    // 17 位加权因子
    private static final int[] RATIO_ARR = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};

    // 校验码列表
    private static final char[] CHECK_CODE_LIST = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};

    private static final int NUM_0 = '0';

    private final int ID_LENGTH = 17;

    public boolean verifyId18(String idNo) {
        if (idNo == null || idNo.isEmpty()) {
            return false;
        }
        idNo = idNo.trim();
        if (idNo.length() != 18) {
            return false;
        }
        // 获取身份证号字符数组
        char[] idCharArr = idNo.toCharArray();
        // 获取最后一位(身份证校验码)
        char verifyCode = idCharArr[ID_LENGTH];
        // 身份证号第1-17加权和
        int idSum = 0;
        // 余数
        int residue;

        for (int i = 0; i < ID_LENGTH; i++) {
            int value = idCharArr[i] - NUM_0;
            idSum += value * RATIO_ARR[i];
        }
        // 取得余数
        residue = idSum % 11;
        return Character.toUpperCase(verifyCode) == CHECK_CODE_LIST[residue];
    }
}

另:15 位身份证出生年份采用年份后 2 位,没有最后 1 位校验码

至于为什么要 mod11 >>>这里<<<

你可能感兴趣的:(18 位身份证号码校验算法)