Loading

身份证最后的X是什么

一直以来都有一个疑问? 为什么我的身份证号最后一位是个字母嘞? 别人都是数字的呀? 为了搞懂这个问题, 我专门研究了一下身份证号码的组成.

身份证号码组成

我找到了在1999年9月30号发布国务院公报, 其中第16页对公民身份证号码有这样一段介绍:

公民身份号码按照GB11643-1999《公民身份号码》国家标准编制,由18位数字组成:前6位为行政区划代码,第7至14位为出生日期码,第15至17位为顺序码,第18位为校验码。

这段话很好理解, 简单的说明了身份证号码的组成:

  • 1-6: 行政区的代码. 具体可见官方行政区划代码
  • 7-14: 出生日期. 如: 19970123
  • 15-17: 顺序码. 当同一天的同一地区出生时用于区分, 奇数为男偶数为女. (也就是说如果一个县一天的新生儿超过500就不够用了)
    • 比如, 当天第一个出生的男生为001, 第二个出生的男生为003, 以此类推
  • 18: 校验码. 主要是为了防止填写身份证号码是填错了一位, 使用此校验码进行校验.

好, 现在对身份证号码的组成基本没有疑问了, 除了最后一位校验码.

身份证校验码

校验码的出现, 可以对前17位身份证号码进行检验, 以防止错填的情况发生.

找到了一篇官方对校验码生成的说明文章: 审计中身份证校验码检验的ASL实现

简单来说步骤如下:

  1. 将前17位数字分别与各自的系数相加, 并求的和 S
    • 从第1位到17位, 系数分别为: [7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2]
    • 悄悄告诉你, 若位数为i, 则系数的计算规则为 x=2^(18-i) % 11
  2. 将和与11取模, Q=S%11
  3. 则余数Q0-10的11个数字, 分别对应校验码[1,0,X,9,8,7,6,5,4,3,2]

校验码的计算值为0-10. 到这里想必猜也猜到了, 为了保证身份证号码的位数一致, 使用X来代表数字10. (再悄悄告诉你, X并不是个字母哦, 它是罗马数字10)

举个例子来介绍校验码的计算吧:

若身份证号的前17位为: 13063419970101001. 那么余数则为:

(1*7 + 3*9 + 0*10 + 6*5 + 3*8 + 4*4 + 1*2 + 9*1 + 9*6 + 7*3 + 0*7 + 1*9 + 0*10 + 1*5 + 0*8 + 0*4 + 1*2) % 11= 8

根据索引, 校验码为4.

使用PHP来计算的话如下所示:

<?php

$card="13063419970101001"; //身份证号码
$map = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2];
$sum = 0;
for ($i = 0; $i < 17; $i++){
    // 计算校验码系数
    $x = pow(2, 17-$i) % 11;
    $sum += $x * $card[$i];
}
// 校验码
echo $map[$sum % 11];

至于为什么校验码是这样设计的, 涉及到数学问题, 在此按下不表.

至此, 终于明白为什么我有一个X

posted @ 2022-10-05 22:17  烟草的香味  阅读(529)  评论(0编辑  收藏  举报