1. 前言
中華人民共和國國家標准GB 11643-1999《公民身份號碼》中規定:公民身份號碼是特征組合碼,由17位數字本體碼和1位校驗碼組成。
18位數字組合的方式是:
其中,最后一位是校驗碼,它是由前17位數字按照某種計算方式計算出來的。校驗碼為一位數,但如果最后采用校驗碼系統計算的校驗碼是“10”,礙於身份證號碼為18位的規定,則以“X”代替校驗碼“10”。
計算方式如下:
- 將身份證號碼從左至右標記為 a 1 , a 2 , ⋯ , a 18 \displaystyle a_{1},a_{2},\cdots ,a_{18} a1,a2,⋯,a18; a 18 \displaystyle a_{18} a18即為校驗碼;
- 計算權重系數 W i = 2 18 − i m o d 11 \displaystyle W_{i}=2^{18-i}\ {\bmod {\ }}{11} Wi=218−i mod 11;其中 m o d \displaystyle \ \bmod {\ } mod 表示求余數。
i i i | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
W i W_{i} Wi | 7 | 9 | 10 | 5 | 8 | 4 | 2 | 1 | 6 | 3 | 7 | 9 | 10 | 5 | 8 | 4 | 2 |
- 計算 S = ∑ i = 1 17 a i ⋅ W i \displaystyle S=\sum _{i=1}^{17}a_{i}\cdot W_{i} S=i=1∑17ai⋅Wi
- 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