日常练习-利用python的random模块模拟身份证号码

⽇常练习-利⽤python的random模块模拟⾝份证号码
前段时间做了⼀个数据库的课设,其中初始⾝份证号码数据的导⼊引起了我的思考,于是下⾯的⾝份证号⽣成代码便诞⽣了:
1import csv
2import os
3import 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
24class CreateIdCardNumber:
25"""⽣成⾝份证号码"""
26
27def__init__(self, numbers=200):
28# ⽤来存放要⽣成的⾝份证号的数量
29        self.numbers = numbers
30# ⽤来存放⽣成的⾝份证号码
31        self.id_card_numbers = []
32
33    @staticmethod
34def get_administrative_division_code():
35"""获取⾏政区划编码"""
36# 拼接⽂件的地址
37        filename = os.path.dirname(
38            alpath(__file__)) + '/⾏政区划代码.csv'
39# 读取⾏政区划编码的csv⽂件
40        with open(filename, 'r', encoding='UTF-8') as f:
41            reader = ader(f)
42# 存放⾏政区划编码
43            administrative_division_codes = []
44# 逐⼀遍历,不存在就跳过,存在就加⼊
45for row in reader:
46try:
47                    number = row[0]
48except ValueError:
49print(f"Missing data {row[1]}")
50else:
51                    administrative_division_codes.append(number)
52# 将⾏政区划编码列表返回去
53return administrative_division_codes[1:]
54
55    @staticmethod
56def year_month_day():
57# ⽤来存放⽣成的年⽉⽇
58        year_month_day = []
59# ⽣成500个⽇期
60        number = 500
61while number != 0:
62# 随机⽣成年⽉
63            year = str(random.randint(1990, 2000))
64            month = str(random.randint(1, 12)).zfill(2)
65# 根据⽉份确定天的随机数
66if month in ['01', '03', '05', '07', '08', '10', '12']:
67                day = str(random.randint(1, 31)).zfill(2)
68elif month in ['04', '06', '09', '11']:
69                day = str(random.randint(1, 30)).zfill(2)
70else:
71                day = str(random.randint(1, 29)).zfill(2)
72# 临时存放⽣成的年⽉⽇,好⽤于后⾯的判断
73            result = year + month + day
74if result not in year_month_day:
75                year_month_day.append(result)
76                number -= 1
77# 将年⽉⽇列表返回
78return year_month_day
79
80    @staticmethod
81def sequence_code():
82# ⽤来存放⽣成的顺序码
83        sequence_code = []
84# ⽣成500个顺序码
85        number = 500
86while number != 0:
87# 直接对1000进⾏取随机值
88# 临时存放随机值,好⽤于后⾯的判断
89            result = str(random.randint(0, 1000)).zfill(3)
90if result not in sequence_code:
91                sequence_code.append(result)
92                number -= 1
93# 将⽣成的顺序码返回
94return sequence_code
95
96def check_code(self):
97# 通过调⽤前⾯的函数⽣成17个字符的字符串
98        digits = random._administrative_division_code())[0] + \
99                  random.choices(
100                      ar_month_day())[0] + \
101                  random.choices(self.sequence_code())[0]
102# 根据ISO 7064:1983.MOD 11-2校验码算法
103# 要⽤不⾜补0,应为可能为空
104try:
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
123except Exception as f:
124# 出错了就将错误信息打印出来
125print(f)
126else:
127# 如果校验码是10就转换为x,其他的就去其数值
128            check_code = str(
129                temporary_check_code) if temporary_check_code != 10 else'x' 130# 将⽣成的以为校验码返回
131return check_code
132
133def create_id_card_number(self):
134"""⽣成⾝份证号码"""
135# 在给定的数内循环
136while self.numbers != 0:
137# 临时存放⽣成的⾝份证号码,好⽤于后⾯的判断
138            result = random._administrative_division_code())[ 139                          0] + random.ar_month_day())[0] + \
140                      random.choices(
141                          self.sequence_code())[0] + self.check_code()
142# 判断,存在就跳过,否者就加⼊
143if result not in self.id_card_numbers:
144                self.id_card_numbers.append(result)
145                self.numbers -= 1
146# 将⽣成的⾝份证号码返回
147return self.id_card_numbers
148
149
150if__name__ == '__main__':
151print(CreateIdCardNumber(100).create_id_card_number())

本文发布于:2024-09-21 16:47:14,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/2/479987.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:数字   校验码   代码   区划   编码   代表   返回   证号码
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议