【python】身份证号码有效性校验

1. 前言

中华人民共和国国家标准GB 11643-1999《公民身份号码》中规定:公民身份号码是特征组合码,由17位数字本体码和1位校验码组成。

18位数字组合的方式是:
在这里插入图片描述
其中,最后一位是校验码,它是由前17位数字按照某种计算方式计算出来的。校验码为一位数,但如果最后采用校验码系统计算的校验码是“10”,碍于身份证号码为18位的规定,则以“X”代替校验码“10”。

计算方式如下:

  1. 将身份证号码从左至右标记为 a 1 , a 2 , ⋯   , a 18 \displaystyle a_{1},a_{2},\cdots ,a_{18} a1,a2,,a18 a 18 \displaystyle a_{18} a18即为校验码;
  2. 计算权重系数 W i = 2 18 − i     m o d     11 \displaystyle W_{i}=2^{18-i}\ {\bmod {\ }}{11} Wi=218i mod 11;其中     m o d     \displaystyle \ \bmod {\ }  mod 表示求余数。
i i i1234567891011121314151617
W i W_{i} Wi7910584216379105842
  1. 计算 S = ∑ i = 1 17 a i ⋅ W i \displaystyle S=\sum _{i=1}^{17}a_{i}\cdot W_{i} S=i=117aiWi
  2. a 18 = ( 12 − ( S     m o d   1 1 ) )   m o d   1 1 \displaystyle a_{18}=(12-(S\ {\bmod {1}}1)){\bmod {1}}1 a18=(12(S mod11))mod11

2. 代码

def main(id):
    sum = 0
    for index, item in enumerate(id[:-1]):
        sum += 2**(17-index) % 11*int(item)
    num = (12 - sum % 11) % 11
    if num < 10:
        return '校验通过' if id[-1] == str(num) else f'校验失败,正确尾号应为:{num}'
    else:
        return '校验通过' if id[-1] == 'X' else f'校验失败,正确尾号应为:{num}'


if __name__ == '__main__':
    test_id_1 = '532527195503267352'
    test_id_2 = '53252719550326735X'
    print(main(test_id_1))
    print(main(test_id_2))


'''输出
校验通过
校验失败,正确尾号应为:2
'''

3. 注意

正确的校验码是身份证号码有效性的必要条件,而非充分条件。要保证身份证号码的有效性,其它条件也要满足,比如号码位数必须为18位,地址码要符合中华人民共和国关于行政区划代码的规定,还有就是出身日期码也要合法等等。有兴趣的话,你可以自己编程实现。当然,这里也提供一个已经封装好的python第三方库id-validator

3.1. 安装

pip install id-validator

3.2. 使用

3.2.1. 验证身份证号合法性

验证身份证号是否合法,合法返回 True,不合法返回 False:

>>> from id_validator import validator
>>> validator.is_valid('440308199901101512')
True
>>> validator.is_valid('44030819990110151X')
False

3.2.2. 获取身份证号信息

当身份证号合法时,返回分析信息(地区、出生日期、星座、生肖、性别、校验位),不合法返回 False:

>>> from id_validator import validator
>>> validator.get_info('440308199901101512')
{
    "address_code": "440308",
    "abandoned": 0,
    "address": "广东省深圳市盐田区",
    "address_tree": [
        "广东省",
        "深圳市",
        "盐田区"
    ],
    "age": 22,
    "birthday_code": "1999-01-10",
    "constellation": "摩羯座",
    "chinese_zodiac": "卯兔",
    "sex": 1,
    "length": 18,
    "check_bit": "2"
}

3.2.3. 生成可通过校验的假数据

伪造符合校验的身份证:

>>> from id_validator import validator
>>> validator.fake_id()
'410704200302268552'

4. 参考

https://zh.wikipedia.org/wiki/中华人民共和国公民身份号码
https://github.com/jxlwqq/id-validator.py

posted @ 2021-01-21 00:48  XavierJ  阅读(2142)  评论(0编辑  收藏  举报