身份证对我们来说可谓是息息相关的。身份证就是身份的证明,不论是出行坐船、坐火车、坐飞机,还是出门办事情都离不开这个“宝贝”。
我们都知道身份证是由18位数字(或者最后一位是X)构成的,那么具体这些数字每一位是如何设置的呢?
身份证号码组成
下面这个表给出了各位数字的由来。首先是前六位,这六位是地址码,就是户口所在地的对应编号,如下图 110105 就是北京朝阳区的编号;中间的八位是出生日期码,对应年月日。
接着第十五和十六位是顺序码,具体指同一地址码所标识的区域范围内,对同年同月同日出生的(也就是前十四位完全相同)人员编订的顺序号;倒数第二位则是性别码,若男性则为奇数,女性则为偶数;而最后一位则是校验码,根据一种校验规则得到的数字,如果按照校验规则得到数字为十,则用 X 来代替。
校验规则
校验码(身份证最后一位)是根据前面十七位数字码,按照ISO7064:1983.MOD11-2 校验码计算出来的检验码。具体的计算方法如下:
- 将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4-2。
- 将这17位数字和系数相乘的结果相加。
- 用加出来和除以11,看余数是多少?
- 余数只可能有0-1-2-3-4-5-6-7-8-9-10这11个数字。其分别对应的最后一位身份证的号码为1-0-X -9-8-7-6-5-4-3-2。(即余数0对应1,余数1对应0,余数2对应X...)
根据校验规则,我们可以通过 Python 来实现一个简单的身份证校验的功能。
def id2code(s):
coe = {0: 7, 1: 9, 2: 10, 3: 5, 4: 8, 5: 4, 6: 2, 7: 1, 8: 6, 9: 3, 10: 7, 11: 9, 12: 10, 13: 5, 14: 8, 15: 4, 16: 2}
sum_num = 0
l = []
for i in s[:17]:
l.append(int(i))
for i in range(17):
sum_num = sum_num + coe[i] * l[i]
return sum_num % 11
构造一个 coe 系数字典,计算得到余数,再按照映射关系得到第十八位。最后与输入的身份证号的最后一位比对,即可做出一个简单的判断。
安全问题
根据这些知识我们会发现,想要得到一个人的身份证号码相当容易,尤其是和你有些接触的人。他们知道你的户口所在地,知道你的生日,这些在你的社交网络中甚至是公开的信息。
这样他们就掌握了你的身份证的前十四位准确信息。根据你的性别还能确定第十七位的奇偶性,而由于第十八位只是一个校验位,因此仅仅需要猜测2.5位的信息。一共也就10105=500种可能,这点计算对计算机来说简直小菜一碟,暴力枚举就可以破解。而身份证号码的暴露,可能也会带来诸多风险,对个人带来不好的影响。