18 位身份证号码校验算法

作者: 为何是Hex的昵称 | 来源:发表于2017-06-23 14:19 被阅读253次

    因项目需要,在绑定银行卡的时候,需要校验身份证号码是否合法,于是去 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 位身份证号码校验算法

        本文链接:https://www.haomeiwen.com/subject/pylccxtx.html