18位身份证校验

作者: 甚时跃马归来 | 来源:发表于2019-04-01 17:38 被阅读0次

    导言

    在我们的日常开发中,很容易碰到需要实名验证的场景,因此本文主要记录一下18位身份证号码的校验。

    身份证规则说明

    第二代身份证的编码规则如下:
    户口登记地行政区划代码(6位) + 出生年月日(8位) + 顺序码(3位) + 校验码(1位)

    详细说明:
    户口登记地行政区划代码:(注意:可能有些地区的行政区划代码会有所变更,所以这份资料也不一定完整。)详细见行政区划代码
    出生年月日:没有什么需要注意的
    顺序码:奇数为男性 偶数为女性
    校验码: 用于身份证号码的校验(详情见下方)。

    校验码算法

    身份证校验方法:将本体码各位数字乘以对应的加权因子并求和,除以11得到余数,根据余数通过校验码对照表查得校验码。

    加权因子:


    加权因子.png

    校验码:


    校验码.png

    算法例子:
    本体码为11010519491231002

    第一步: 各位数与对应加权因子乘积求和17+19+010+15+***=167

    第二步:对求和进行除11得余数167%11=2

    第三步:根据余数2对照校验码得X

    因此完整身份证号为:11010519491231002X

    js代码示例(包含长度、出生年月、性别、校验码校验等4重校验。)

    function checkCardId(cardId){
        
        // 0 、校验长度
        if(cardId.length !== 18){
            return {
                code : 404,
                message : '身份证号码错误,请检查!'
            }
        }
        
        // 1 、号码规则校验(未验证,如果要用到此部分代码请自行验证。)
    //  var format = /^(([1][1-5])|([2][1-3])|([3][1-7])|([4][1-6])|([5][0-4])|([6][1-5])|([7][1])|([8][1-2]))\d{4}(([1][9]\d{2})|([2]\d{3}))(([0][1-9])|([1][0-2]))(([0][1-9])|([1-2][0-9])|([3][0-1]))\d{3}[0-9xX]$/;
    //  if (!format.test(cardId)) {
    //      return {
    //          code : 404,
    //          message : '校验不通过'
    //      };
    //  }
        
        // 2、出生年月校验(固定位置)
        let year = cardId.substr(6,4);
        let month = cardId.substr(10,2);
        let day = cardId.substr(12,2);
        let birthday = `${year}-${month}-${day}`;
        if(!checkBirthday(birthday)){
            console.log(birthday);
            return {
                code : 404,
                message : '校验失败'
            }
        }
        
        // 3、 性别校验(需要的就打开注释)
    //  let sexCode = cardId.substr(14,3);
    //  if(sexCode % 2 === 1){
    //      console.log('男性');
    //  }else{
    //      console.log('女性');
    //  }
        
        // 4、校验码校验
        // 提取最后一位校验码
        let code = cardId.substr(17, 1);
        // 提取需要校验的字符串(前17位)
        let checkStr = cardId.substr(0,17);
         
        let sum = 0; 
        // 加权因子
        let ruleArr = [7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2];
        // 使用加权因子计算所得结果对应的校验码(模11,有10种结果)
        let checkCodeArr = [1,0,'x',9,8,7,6,5,4,3,2];
        
        
        checkStr.split('').map(function(item,index){
            sum += Number(item)*ruleArr[index];
        })
        
        let checkNum = sum % 11;
        let caculateCode = checkCodeArr[checkNum];
        if(checkNum === 2){
            code = code.toLowerCase();
        }else{
            code = Number(code);
        }
        
        if(caculateCode === code){
            return {
                code : 200,
                message : '校验通过'
            }
        }else{
            return {
                code : 404,
                message : '校验不通过'
            }
        }
    }
    
    function checkBirthday(birthday){
        var r = /^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$/;
        if(!r.test(birthday)){
            return false;
        }else{
            return true;
        }
    }
    

    附注

    通过此校验并不代表身份证是有效的!!!

    参考资料

    身份证规则解析
    行政区划代码资料

    相关文章

      网友评论

        本文标题:18位身份证校验

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