日常練習-利用python的random模塊模擬身份證號碼


前段時間做了一個數據庫的課設,其中初始身份證號碼數據的導入引起了我的思考,於是下面的身份證號生成代碼便誕生了:

  1 import csv
  2 import os
  3 import random
  4 
  5 
  6 # 1、前1、2位數字代表所省份代碼;
  7 # 2、第3、4位數字代表所城市代碼;
  8 # 3、第5、6位數字代表所區縣代碼;
  9 # 4、第7~14位數字代表的是第7,8,9,10位為出生年份,第11.12位代表出生月份,第13,14位代表出生日期;
 10 # 5、第15~17位是順序碼。同一地址碼所標識的區域范圍內,對同年、月、日出生的人員編定的順序號。其中第十七位奇數分給男性,偶數分給女性。
 11 # 6、第18位數字為校檢碼:校檢碼0~9數字,10用X表示。這是根據前面十七位數字碼,按照ISO 7064:1983.MOD 11-2校驗碼計算出來的檢驗碼。
 12 # ISO 7064:1983.MOD 11-2校驗碼的例子:
 13 #     假設某一17位數字是
 14 #     17位數字       1     2     3     4     5     6     7     8     9     0     1     2     3     4     5     6     7
 15 #     加權因子       7     9     10    5     8     4     2     1     6     3     7     9     10    5     8     4     2
 16 #     計算17位數字各位數字與對應的加權因子的乘積的和S:1×7+2×9+3×10+4×5+5×8+6×4+7×2+8×1+9×6+0×3+1×7+2×9+3×10+4×5+5×8+6×4+7×2=368;
 17 #     計算S÷11的余數T:368 mod 11=5;
 18 #     ((  余數0-10對應校驗碼為[1, 0, X , 9, 8, 7, 6, 5, 4, 3, 2],算法如下 ))
 19 #     計算(12-T)÷11的余數R,如果R=10,校驗碼為字母“X”;如果R≠10,校驗碼為數字“R”:(12-5)mod 11=7。
 20 #     該17位數字的校驗碼就是7,聚合在一為123456789012345677。
 21 
 22 # 假設職工的生日在1990.1.1——2000.1.1
 23 
 24 class CreateIdCardNumber:
 25     """生成身份證號碼"""
 26 
 27     def __init__(self, numbers=200):
 28         # 用來存放要生成的身份證號的數量
 29         self.numbers = numbers
 30         # 用來存放生成的身份證號碼
 31         self.id_card_numbers = []
 32 
 33     @staticmethod
 34     def get_administrative_division_code():
 35         """獲取行政區划編碼"""
 36         # 拼接文件的地址
 37         filename = os.path.dirname(
 38             os.path.realpath(__file__)) + '/行政區划代碼.csv'
 39         # 讀取行政區划編碼的csv文件
 40         with open(filename, 'r', encoding='UTF-8') as f:
 41             reader = csv.reader(f)
 42             # 存放行政區划編碼
 43             administrative_division_codes = []
 44             # 逐一遍歷,不存在就跳過,存在就加入
 45             for row in reader:
 46                 try:
 47                     number = row[0]
 48                 except ValueError:
 49                     print(f"Missing data {row[1]}")
 50                 else:
 51                     administrative_division_codes.append(number)
 52         # 將行政區划編碼列表返回去
 53         return administrative_division_codes[1:]
 54 
 55     @staticmethod
 56     def year_month_day():
 57         # 用來存放生成的年月日
 58         year_month_day = []
 59         # 生成500個日期
 60         number = 500
 61         while number != 0:
 62             # 隨機生成年月
 63             year = str(random.randint(1990, 2000))
 64             month = str(random.randint(1, 12)).zfill(2)
 65             # 根據月份確定天的隨機數
 66             if month in ['01', '03', '05', '07', '08', '10', '12']:
 67                 day = str(random.randint(1, 31)).zfill(2)
 68             elif month in ['04', '06', '09', '11']:
 69                 day = str(random.randint(1, 30)).zfill(2)
 70             else:
 71                 day = str(random.randint(1, 29)).zfill(2)
 72             # 臨時存放生成的年月日,好用於后面的判斷
 73             result = year + month + day
 74             if result not in year_month_day:
 75                 year_month_day.append(result)
 76                 number -= 1
 77         # 將年月日列表返回
 78         return year_month_day
 79 
 80     @staticmethod
 81     def sequence_code():
 82         # 用來存放生成的順序碼
 83         sequence_code = []
 84         # 生成500個順序碼
 85         number = 500
 86         while number != 0:
 87             # 直接對1000進行取隨機值
 88             # 臨時存放隨機值,好用於后面的判斷
 89             result = str(random.randint(0, 1000)).zfill(3)
 90             if result not in sequence_code:
 91                 sequence_code.append(result)
 92                 number -= 1
 93         # 將生成的順序碼返回
 94         return sequence_code
 95 
 96     def check_code(self):
 97         # 通過調用前面的函數生成17個字符的字符串
 98         digits = random.choices(self.get_administrative_division_code())[0] + \
 99                  random.choices(
100                      self.year_month_day())[0] + \
101                  random.choices(self.sequence_code())[0]
102         # 根據ISO 7064:1983.MOD 11-2校驗碼算法
103         # 要用不足補0,應為可能為空
104         try:
105             temporary_check_code = (12 - (
106                     int(digits[0:1].zfill(1)) * 7 + int(
107                 digits[1:2].zfill(1)) * 9 + int(
108                 digits[2:3].zfill(1)) * 10 + int(
109                 digits[3:4].zfill(1)) * 5 + int(
110                 digits[4:5].zfill(1)) * 8 + int(
111                 digits[5:6].zfill(1)) * 4 + int(
112                 digits[6:7].zfill(1)) * 2 + int(
113                 digits[7:8].zfill(1)) * 1 + int(
114                 digits[8:9].zfill(1)) * 6 + int(
115                 digits[9:10].zfill(1)) * 3 + int(
116                 digits[10:11].zfill(1)) * 7 + int(
117                 digits[11:12].zfill(1)) * 9 + int(
118                 digits[12:13].zfill(1)) * 10 + int(
119                 digits[13:14].zfill(1)) * 5 + int(
120                 digits[14:15].zfill(1)) * 8 + int(
121                 digits[15:16].zfill(1)) * 4 + int(
122                 digits[16:17].zfill(1)) * 2) % 11) % 11
123         except Exception as f:
124             # 出錯了就將錯誤信息打印出來
125             print(f)
126         else:
127             # 如果校驗碼是10就轉換為x,其他的就去其數值
128             check_code = str(
129                 temporary_check_code) if temporary_check_code != 10 else 'x'
130             # 將生成的以為校驗碼返回
131             return check_code
132 
133     def create_id_card_number(self):
134         """生成身份證號碼"""
135         # 在給定的數內循環
136         while self.numbers != 0:
137             # 臨時存放生成的身份證號碼,好用於后面的判斷
138             result = random.choices(self.get_administrative_division_code())[
139                          0] + random.choices(self.year_month_day())[0] + \
140                      random.choices(
141                          self.sequence_code())[0] + self.check_code()
142             # 判斷,存在就跳過,否者就加入
143             if result not in self.id_card_numbers:
144                 self.id_card_numbers.append(result)
145                 self.numbers -= 1
146         # 將生成的身份證號碼返回
147         return self.id_card_numbers
148 
149 
150 if __name__ == '__main__':
151     print(CreateIdCardNumber(100).create_id_card_number())

行政區划代碼:https://files.cnblogs.com/files/wz46265381/%E8%A1%8C%E6%94%BF%E5%8C%BA%E5%88%92%E4%BB%A3%E7%A0%81.7z


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM