身份证号码编码规则及校验位校验算法

一、身份证号码作为独一无二代表公民信息的号码,它的组成是由一下的数字表示的:
(1)第1、2位数字表示:所在省(直辖市、自治区)的代码;
(2)第3、4位数字表示:所在地级市(自治州)的代码;
(3)第5、6位数字表示:所在区(县、自治县、县级市)的代码;
(4)第7—14位数字表示:出生年、月、日;
(5)第15、16位数字表示:所在地的派出所的代码;
(6)第17位数字表示性别:奇数表示男性,偶数表示女性;
(7)第18位数字是校检码:是根据《中华人民共和国国家标准GB 11643-1999》中有关公民身份号码的规定,根据精密的计算公式计算出来的。

二、校验码的计算方法:
1、将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7、9、10、5、8、4、2、1、6、3、7、9、10、5、8、4、2 ;
2、将这17位数字和系数相乘的结果相加;
3、用加出来和除以11,看余数是多少;
4、余数只可能有0、1、2、3、4、5、6、7、8、9、10这11个数字。其分别对应的最后一位身份证的号码为1、0、X、9、8、7、6、5、4、3、2,其中的X是罗马数字10;
5、通过上面得知如果余数是2,就会在身份证的第18位数字上出现罗马数字的Ⅹ;如果余数是10,身份证的最后一位号码就是2

 



/**
 * 身份证验证规则:
 * 第十八位数字(校验码)的计算方法为:
 * 1.将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
 * 2.将这17位数字和系数相乘的结果相加与11进行相除。
 * 3.余数0 1 2 3 4 5 6 7 8 9 10这11个数字,其分别对应的最后一位身份证的号码为1 0 X 9 8 7 6 5 4 3 2。
 * 4.例如 余数为 0 , 则身份证最后一位就是1
 *       余数为 2 , 则身份证最后一位就是罗马数字X
 *       余数为 10 , 则身份证最后一位就是2
 * @ClassName: IdCardUtil
 * @date: 2019/10/24 17:10
*/
@Slf4j
public class IdCardUtil {
    /**
     * 校验是否为身份证号码
     * @param IdCardNo
     * @return
     */
    public static  boolean isIdCardNo(String IdCardNo){

        boolean IdCardflag =  false;

        try {

            if (!StringUtils.isEmpty(IdCardNo) && IdCardNo.length() == 18){
                // 1.将身份证号码前面的17位数分别乘以不同的系数。
                int[] coefficientArr = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
                int sum = 0;
                for (int i = 0; i < coefficientArr.length; i++) {
                    // Character.digit 在指定的基数返回字符ch的数值。如果基数是不在范围内MIN_RADIX≤基数≤MAX_RADIX或如果该值的通道是不是一个有效的数字在指定的基数-1,则返回。
                    // ch - the character to be converted(要转换的字符)
                    // ch - int类型,是字符的ASCII码,数字的ASCII码是48-57
                    // radix - the radix(基数) ----也就是进制数
                    sum += Character.digit(IdCardNo.charAt(i), 10) * coefficientArr[i];
                }

                // 余数数组
                int[] remainderArr = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

                // 身份证号码第18位数组
                int[] lastArr = { 1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2 };
                String matchDigit = "";
                for (int i = 0; i < remainderArr.length; i++) {
                    int j = remainderArr[i];
                    if (j == sum % 11) {
                        matchDigit = String.valueOf(lastArr[i]);
                        if (lastArr[i] > 57) {
                            matchDigit = String.valueOf((char) lastArr[i]);
                        }
                    }
                }

                if (matchDigit.equals(IdCardNo.substring(IdCardNo.length() - 1))) {
                    IdCardflag =  true;
                }
            }

        }catch (Exception e) {

            log.error(String.format("校验身份证出现异常%s",e));
        }

        return  IdCardflag;

    }

    /**
     * 身份证号码脱敏 只脱敏月日四位
     */
    public  static  String getNewIdCardNo(String IdCardNo){

        String IdCardNoTemmp = IdCardNo;
        if (isIdCardNo(IdCardNo)){
            StringBuilder sb = new StringBuilder(IdCardNo);
            sb.replace(10, 14, "****");
            IdCardNoTemmp = sb.toString();
        }

        return IdCardNoTemmp;
    }
}

 

  • 9
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值