中国身份证校验

Check Chinese ID

号码组合含义

目前中国使用的18位身份证号由6位地址码+8位生日+3位顺序码+1位校验码组成。

地址码指的是公民出生地所在县(市、镇、区)的行政区划代码,如310110是上海市杨浦区。但港澳臺地區居民的身份號碼只精確到省級。

出生日期码表示公民出生的公历年(4位)、月(2位)、日(2位)。

顺序码是给同地址码同出生日期码的人编定的顺序号,其中奇数分配给男性,偶数分配给女性。

最后一位是校验码,这里采用的是ISO 7064:1983, MOD 11-2校验码系统。校验码为一位数,但如果最后采用校验码系统计算的校验码是“10”,碍于身份证号码为18位的规定,则以“X”代替校验码“10”。

校验码计算方法

  1. 将身份证号码从左至右标记为 a1, a2, ⋯, a18,a_{18}即为校验码;
  2. 计算权重系数 $W_i = 2^{18 − i} \mod 11$
i 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
W 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 1
  1. 计算 $S = \sum\limits_{i=1}^{17} a_i * W_i$
  2. $a_{18} = (12 - (S \mod 11)) \mod 11$
1
2
3
4
5
6
7
8
def check_china_id(id_num:str) -> bool:
    assert len(id_num) == 18
    S = 0
    for i in range(17):
        S += int(id_num[i]) * 2 ** (17 - i) % 11
    checksum = (12 - (S % 11)) % 11
    checkchar = str(checksum) if checksum < 10 else 'X'
    return checkchar == id_num[17]

一些奇怪的用处

首先当然是基本查验接触到的中国身份证号是否正确。

中国网络实行普遍的实名制,尤其电子游戏需要绑定身份信息,而游戏公司是不能也不应该实时接入公安数据库的,那么就可以按照这一规则生成一个假的身份证通过验证。 金融领域也可以这样申请一些账户,但由于金融行业和公安数据对接更紧密,会定期对比身份信息,随机生成的身份证号很快会露出破绽。

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy