身份证号的结构和疑问
最近因为业务的关系,需要了解中国的行政区划。从网上下载数据集,发现区划代码和身份证的前缀非常相似。遂做了一些深入的研究。
结构
身份证号码有如下结构:
ID := {province:2}{city:2}{area:2}{birthday:8}{random:3}{check:1}
check := mod(sum(pres), 11) as m, x if m == 10 else m
前两位是省级码,2位,其中按第一位的不同区分不同大区。1开头:华北,2开头:东北,3开头:华东,4开头:中南,5开头:西南,6开头:西北,71:台湾,81:香港,82:台湾。
第3~4位,地市级码,地5~6位,县级码。
第7~14位,生日码,持有人的出生年月日。
第15~17位,随机码。
第18位,校验位,前17位加权求和再对11取余数,如果余数是10,则此位是「x」,否则直接是此余数。具体如下,
i := 1, 2, ..., 17
w_i = 2 ^ (18 - i) % 11 # 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2
v = sum(X * W) % 11
最后,为了保证编号的唯一性,行政区划若有变更,原有区划代码不再赋予其他行政区划。
疑问
针对这样的结构,产生了以下疑问:
1. 行政区划调整后,个人身份证号需要调整更新吗?
建国后,行政区划做了不少调整。省级的包括重庆市直辖,地市级以下的就更多了,调整后,区位码会变化,似乎身份证号码也应该变化。
我出生后,所在的行政区划调整过,区位码也改变了,但我的身份证号区位码仍然是旧的,所以,答案是不会调整。新注册的用新的区位码,旧区位码仍然可用。
从另外一个角度看,省市这样的区划调整,涉及千万甚至上亿人,相关数据的更新,和证件的替换,将会耗费巨大的工作量,同步更新是不可行的。
身份证号主要的功能是唯一标识一个社会成员,相关区位码的设定,只是为管理过程提供了一些便利,并不一定要严格遵循。
2. 校验位为什么要模11呢,而不是直接模10?
大部分人的身份证号上都没有X,容易造成误解,认为身份证号全由数字组成,而实际上可以包含字母X,在使用中可能造成不便。
查找定义来源:GB 11643-1999,并未解释原因。猜测可能的原因:11是素数,对素数取模更随机。我们知道,如果原数有某种规律非随机,对素数取模,会更随机。如果原数,很随机,比如是随机生成的数,那么是否对素数取模则不太必要。身份证号包含区位码和生日部分,随机性较差,对素数取模也是合理的选择。不过由此导致在看上去应该都是数字的编号中出现字母X,可能一些系统的实现带来额外的麻烦。
3. 同一地区同一天的号池容量是1000个,如果同一天出生超过1000人怎么办?
全国大概3000个县级区域,按2021年大概1000万的出生人口,平均一个县级区域一天的出生人口大概为:1000万/3000/365 = 9,远小于1000。所以,这种情况可能还没有碰到过。如果真碰到了,可能需要将省份证上的生日延后了。
4. 各级区位码够用吗?
省、市、县,各占两位,即最多容纳100个下级,当前行政区划,除了省外,打个平均10个下级区划,30个左右省,每个省平均10个市,每个市平均10个县。总共约3000多个县。每级大概有5倍的富余,不过由于区划调整,又占用了不少,但应该还有富余。
短期内不会碰到用尽的情况,如果真没有区位码可用,回收废弃且没有在使用的区位可以是一个方法,或者直接增加区位码的长度。
5. 日期有8位,四位是年份,那么8000年后怎么办?
太遥远了,后人自有办法。过早优化,过度设计,是万恶之源。