一行代码 一世浮生

你真的理解身份证号码背后的数学知识吗?

可以搜索微信公众号【Jet 与编程】查看更多精彩文章


一、背景

身份证号码是中国大陆每个人的身份标识,是唯一的(除开一些老的没有更换的身份证),它记录每个人所有的信息。在日常的银行卡开户、社保开户等都必须使用到,是每个人至关重要的身份信息。

目前大陆的第二代身份证号码是由 18 位数字(最后一位如果是 x 其实代表数字 11)组成的,这 18个数字,每一个都有着深刻的意义。

本文借此 2020 年的契机,以今年的幸运身份证号码为例来进行下解读,这个身份证号码有多幸运呢?因为它的组成只有数字 2 和 0,当你给别人报身份证号的时候,别人还以为你在开玩笑呢。

案例身份证号:220202 20200202 002 2

图解案例身份证号码
图解案例身份证号码

二、前 17 位

身份证号码的前 17 位,其实是比较简单的,绝大部分人也是可以看懂的,我们就以上面的案例身份证为例来解读。

220202:这最前面的 6 位,代表了出生的省市区,即 吉林省 吉林市 昌邑区
20200202:中间的这 8 位,代表了出生的年月日,即 2020 年 2 月 2 日
002:排除末位后倒数的这三个数,是序列号,是按序来排的,也就是按照登记顺序来排序,但是其中的最后一位代表了性别,即奇数代表了男性,偶数代表了女性。

所以说,上述的幸运儿肯定是个位女性。

三、最后一位数字的意义

最后一位,其实是校验码,主要作用是用于校验前面 17 位数字的正确与否。

先说下整个的数学公式吧:

\displaystyle \sum^{18}_{i = 1}{a_i * w_i} \equiv 1 (mod 11)

” ≡ “,称为“同余”
“mod 11″,称为“对 11 取模”

(a_1*w_1 + a_2*w_2 + ... + a_{18}*w_{18})

上述公式的意思是:
按公式 
对 18 位身份证号码进行求和,得出来的值对 11 取模,得到的值必为 1

下标 i
最后一位是 1,然后依次往左,即左边第一位数字的下标是 18

ai
ai 代表每一位身份证号码,比如上述的身份证号码案例,从左到右为:

a_{18}=2
a_{17}=2

。。。

a_{1}=2

wi
wi 的计算公式是:

2^{i-1}(mod 11)

比如上述案例,从左到右依次为:

w_{18}=2^{17}(mod 11)=131072(mod 11) = 7
w_{17}=2^{16}(mod 11)=65536(mod 11) = 9

。。。

w_{1}=2^{0}(mod 11)=1(mod 11) = 1

用表格罗列如下:

所以求和为:

\displaystyle \sum^{18}_{i = 1}{a_i * w_i} = 100

将求和得出的 100 对 11 取模,得出结果为 1,这正是上述公式期望得到的结果。

到此,验证完毕。

所以,赶快掏出自己的身份证号码来验证下吧,是不是打开了新世纪的大门。

四、最后一位数字的生成

上面是使用整个 18 位号码来进行验证的,接下来我们来实现:通过前 17 位数字来计算第 18 位数字

当然,你进行穷举,即最多计算 11 次,也可以计算末尾数字,但是那样岂不是太弱了。

还是老样子,先公布下公式:

[12 - \displaystyle \sum^{18}_{i=2}a_iw_i(mod 11)](mod 11)

公式其实也不难,我们来解读下:

  1. 将前 17 位号码(ai)分别和对应的系数(wi)想乘
  2. 得到的结果进行相加
  3. 将求和得到的值对 11 取模运算
  4. 用 12 减去上面第 4 步得到的值
  5. 再次将上面第 4 步得到的值对 11 取模,得到的数便是身份证号码的末位,该数值必然是 0~10 之间的数字,如果是 10,则使用 X 来表示

还是以上面提到的身份证为例,我们试着来根据前面的 17 位来推算末位数,还是使用表格来画一下:

然后按公式来进行计算:

\begin{align} [12 - \displaystyle \sum^{18}_{i=2}a_iw_i(mod 11)](mod 11) \\ = [12 - 98(mod 11)](mod 11) \\ = (12 - 10)(mod 11) \\ = 2(mod 11) \\ = 2 \end{align}

所以,末位数字就是 2 啦。

很简单吧,快快快,拿出你的身份证来验证下吧。

五、杂谈

很期待看到上面列出来的这个神奇的身份证号的鼠宝宝。

另外,除末位以外的倒数三位,虽然说是按登记顺序进行排序的,但是还有一个规则,就是每个区都会分配一个编号区间,比如上面的 002,其实就是属于 孤店子 这个区域的。

其实,对于上面的案例身份证号码,它并不是唯一的一个只有 2 和 0 的身份证号码,更多的案例,本文暂不赘述。

六、后记

作为程序猿嘛,肯定要用代码来撸一遍算法的,于是手动撸了一套身份证号码的验证程序,代码如下:

PS:只按照上述算法进行校验,地区和年月日等在此不进行校验

执行结果

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注