公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
其中前六位是地址码,通过百度百科我们很容易就可以知道它们每一位的具体含义和某一地区的地址码到底是多少,我在此就不再赘述了。
第七到第十四位是出生日期码,这个很简单,比如我写这段话的日期可以记作:20210128
身份证号码的第十五到十七位是顺序码,表示在同一地址码所标识的区域范围内,对同年、月、日出生的人员编定的顺序号。其中第十七位奇数分给男性,偶数分给女性。我将对这个顺序码进行较为详细的说明。
在这三位顺序码中,第15和16位这两位表示所在地的派出所代码。在前六位地址码中已经具体到县级行政区了,而县公安局会有几个派出所分别负责这个县的不同乡镇,15和16位就是相应的派出所的代码,我知道我们乡的派出所的代码,但是不知道如何方便准确的查询任意一个派出所的代码的方法,如果你知道的话可以告诉我。第17位是真正意义上的“顺序码”,在这个派出所的管辖范围内同一天生日的人,男性按照进行出生登记的先后顺序会被依次标记为1,3,5,7,9。女性按照进行出生登记的先后顺序会被依次标记为2,4,6,8,0。
第18位是校验码,这一位的数字是根据前17位的数字按照ISO7064:1983.MOD11-2算法计算得出的。具体的计算方法如下:
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。(即余数0对应1,余数1对应0,余数2对应X...)
其中的X为大写,代表的是罗马数字10。在写代码时,上面第四步的对应关系可以表示为:(12 - 余数)mod 11,当结果为10时用“X”表示,结果为其它数字时则直接保留。
以下是根据前17位计算第18位校验位数字的python代码,由此也很容易衍生出判断一个18位的数字字符串是否符合身份证号的校验规则的python代码。
一、输入前17位数字计算第18位检验位的python代码:
计算校验位的函数的一种写法
上图的运行结果二、写一个python代码,从键盘输入一个身份证号,输出它是否符合校验规则
仅供参考
注意上面的代码没有进行输入检测,身份证号前17位只能是数字,第18位只能是数字或‘X’,如果输入的参数不合适很可能会出错。
应该指出的是,一个符合身份证号校验规则的号码未必就是真的。是否真的有这个地区代码?是否真的有这个日期?是否真的有这个代号的派出所?是否真的有这么多的人出生?一个真实存在的身份证号和一个真实存在的人真就是对应的吗?
假如有一个乡镇人口为5万,中国现在的人口出生率大约为千分之十,那么这个乡镇每年的出生人口约为500人,平均每天只有约1.37人。也就是说这个乡镇平均每天出生约0.7个男孩,0.7个女孩。所以只要一个乡镇的人口不是很多,则这个乡镇的身份证号的第17位是1或2的概率很大,越往后的概率就越小。如果这个编号经常排到很大甚至不够用了,则说明这个行政区的管辖范围过大,应该进行拆分。(我个人是这样理解的,具体情况我也不太清楚,如果本文有错误欢迎指出。)