详解身份证验证规则

今天来说说身份证验证规则到底是怎么验证的,原理是什么,希望看完本篇你能正确的去理解身份证验证背后的规则。

身份证号码的编码规则

身份证号码共18位,由17位本体码和1位校验码组成。

身份证最后一位是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。作为尾号的校验码,是由号码编制单位按统一的公式计算出来的,如果某人的尾号是0-9,都不会出现X,但如果尾号是10,那么就得用X来代替,因为如果用10做尾号,那么此人的身份证就变成了19位,而19位的号码违反了国家标准,并且我国的计算机应用系统也不承认19位的身份证号码。Ⅹ是罗马数字的10,用X来代替10,可以保证公民的身份证符合国家标准。

  1. 前6位是地址码,表示登记户口时所在地的行政区划代码,依照《中华人民共和国行政区划代码》国家标准(GB/T2260)的规定执行;
  2. 7到14位是出生年月日,采用YYYYMMDD格式;
  3. 15到17位是顺序码,表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编订的顺序号,顺序码的奇数分配给男性,偶数分配给女性,即第17位奇数表示男性, 偶数表示女性;
    第18位是校验码,采用ISO 7064:1983, MOD 11-2校验字符系统,计算规则下一章节说明。

一代身份证与二代身份证的区别在于:

  1. 一代身份证是15位,二代身份证是18位;
  2. 一代身份证出生年月日采用YYMMDD格式,二代身份证出生年月日采用YYYYMMDD格式;
  3. 一代身份证无校验码,二代身份证有校验码。

校验码计算规则

身份证号码中各个位置上的号码字符值应满足下列公式的校验:

下面通过两种方法用某个真实的男性身份证号(5 3 3 2 2 3 1 9 6 3 0 1 0 5 0 9 1 7)来进行通俗易懂的说明身份证验证规则。

方法一(余数对应法)

余数对应法

  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
    • 首先:我们计算5 X 7 + 3 X 3 + 3 X 10+2 X 5+…+1 X 2,前17位的乘积和是258
    • 然后:用258除以11得出余数是5
    • 最后:通过对应规则就可以知道余数5对应的数字是7。所以,这是一个合格的身份证号码

方法二(十八位加权余一法)

按照18位来计算,第一位数的权重是07,第二位是09(见下表)序号从右向左,只要最后的加权和除以11,余数只要是1,那么身份证号码就是正确的。

十八位加权余一法

注意:如果身份证号码第18位是X,那么就按10计算。

其中5 X 7=35,3 X 9=27,3 X 10=30,其余以此类推,
加权求和=35+27+30…..2+7=265;265 % 11其余数是1,所以这个号码是正确的

用JS实现二代身份证的验证

理解了原理和校验规则开始下手敲起来:

<script type="text/javascript">
  /**
   * 以下身份证验证适用于18位的二代身份证号码,身份证通常是由17位本体码和1位校验码组成。
   **/
  function validateIdCard(idCard) {
    //15位和18位身份证号码的正则表达式
    var regIdCard = /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/;
    //如果通过该验证,说明身份证格式正确,但准确性还需计算
    if (regIdCard.test(idCard)) {
      if (idCard.length == 18) {
        var idCardWi = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2); //将前17位加权因子保存在数组里
        var idCardY = new Array(1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2); //这是除以11后,可能产生的11位余数、验证码,也保存成数组,10代表X
        var idCardWiSum = 0; //用来保存前17位各自乖以加权因子后的总和
        for (var i = 0; i < 17; i++) {
          idCardWiSum += idCard.substring(i, i + 1) * idCardWi[i];
        }
        var idCardMod = idCardWiSum % 11;//计算出校验码所在数组的位置
        var idCardLast = idCard.substring(17);//得到最后一位身份证号码
        //如果等于2,则说明校验码是10,身份证号码最后一位应该是X
        if (idCardMod == 2) {
          if (idCardLast == "X" || idCardLast == "x") {
            return "身份证号码验证通过!";
          } else {
            return "您输入的身份证号码有误!";
          }
        } else {
          //用计算出的验证码与最后一位身份证号码匹配,如果一致,说明通过,否则是无效的身份证号码
          if (idCardLast == idCardY[idCardMod]) {
            return "身份证号码验证通过!";
          } else {
            return "您输入的身份证号码有误!";
          }
        }
      }
    } else {
      return "您输入的身份证格式不正确!";
    }
  }
  var inputs =validateIdCard(prompt());
  var ids = document.getElementById("ids").innerHTML=inputs;

</script>

参考资料

  • 中华人民共和国居民身份证法
  • 中华人民共和国国家标准 GB/T 2260-2007 中华人民共和国行政区划代码
  • 中华人民共和国国家标准 GB 11643-1999 公民身份证号码
  • 中华人民共和国国家标准 GB/T 17710-1999 数据处理 校验码系统
  • 中华人民共和国国家标准 GB/T 17710-2008 信息技术 安全技术 校验字符系统
  • ISO 7064:1983 Data processing - Check character systems

   转载规则


《详解身份证验证规则》 三叶雨 采用 知识共享署名 4.0 国际许可协议 进行许可。
  目录