GitHub : https://github.com/jayknoxqu/id-number-util
身份組成方式
中華人民共和國國家標準GB 11643-1999《公民身份號碼》中規定:公民身份號碼是特征組合碼,由十七位數字本體碼和一位校驗碼組成。
18位數字組合的方式是:
| 1 1 0 1 0 2 | Y Y Y Y M M D D | 8 8 | 8 | X |
|---|---|---|---|---|
| 區域碼(6位) | 出生日期碼(8位) | 順序碼(2位) | 性別碼(1位) | 校驗碼(1位) |
區域碼(6位) 出生日期碼(8位) 順序碼(2位) 性別碼(1位) 校驗碼(1位)
•區域碼 指的是公民常住戶口所在縣(市、鎮、區)的行政區劃代碼,如110102是北京市-西城區。但港澳臺地區居民的身份號碼只精確到省級。
•出生日期碼 表示公民出生的公歷年(4位)、月(2位)、日(2位)。
•順序碼 表示在同一區域碼所標識的區域范圍內,對同年、同月、同日出生的人編定的順序號。
•性別碼 奇數表示男性,偶數表示女性。
•最后一位是校驗碼,這里采用的是ISO 7064:1983,MOD 11-2校驗碼系統。校驗碼為一位數,但如果最后采用校驗碼系統計算的校驗碼是“10”,礙于身份證號碼為18位的規定,則以“X”代替校驗碼“10”。
校驗碼計算方法
•1. 將身份證號碼從右至左標記為a_1 , a_2 , /cdots , a_{18},a_1即為校驗碼;
•2. 計算權重系數 W_i=2^{i-1}/ /bmod / {11}
所以:
| i | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Wi | 7 | 9 | 10 | 5 | 8 | 4 | 2 | 1 | 6 | 3 | 7 | 9 | 10 | 5 | 8 | 4 | 2 | 1 |
•3. 計算S = /sum_{i=2}^{18} a_i /cdot W_i
•4. a_1=(12-( S / /bmod 11)) /bmod 11
使用Python獲取身份證校驗碼:
def get_check_digit(id_number): """通過身份證號獲取校驗碼""" check_sum = 0 for i in range(0, 17): check_sum += ((1 << (17 - i)) % 11) * int(id_number[i]) check_digit = (12 - (check_sum % 11)) % 11 return check_digit if check_digit < 10 else 'X'
隨機生成身份證
由上面的組合方式我們可以得出以下代碼:
@classmethoddef generate_id(cls, sex=0): """ 隨機生成身份證號,sex = 0表示女性,sex = 1表示男性 """ # 隨機生成一個區域碼(6位數) area_info = random.randint(0, len(addr)) id_number = str(addr[area_info][0]) # 限定出生日期范圍(8位數) start, end = "1960-01-01", "2000-12-30" days = (datetime.datetime.strptime(end, "%Y-%m-%d") - datetime.datetime.strptime(start, "%Y-%m-%d")).days + 1 birth_days = datetime.datetime.strftime( datetime.datetime.strptime(start, "%Y-%m-%d") + datetime.timedelta(random.randint(0, days)), "%Y%m%d" ) id_number += str(birth_days) # 順序碼(2位數) id_number += str(random.randint(10, 99)) # 性別碼(1位數) id_number += str(random.randrange(sex, 10, step=2)) # 校驗碼(1位數) return id_number + str(cls(id_number).get_check_digit())
新聞熱點
疑難解答