微信小程序开发微信小程序微信小程序开发躺坑之路

18位身份证校验

2019-04-01  本文已影响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;
    }
}

附注

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

参考资料

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

上一篇 下一篇

猜你喜欢

热点阅读