zoukankan      html  css  js  c++  java
  • 日常练习-利用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

  • 相关阅读:
    linux添加自定义命令
    linux 将自己的服务添加到系统service服务
    制作linux下的.run安装包
    Wowza 相关
    深入理解 Vue Computed 计算属性
    养狗相关知识整理
    柯基犬体重对照图
    window下tomcat的内存溢出问题
    postMan测试https接口
    beego获取用户请求参数的方法
  • 原文地址:https://www.cnblogs.com/wz46265381/p/15339542.html
Copyright © 2011-2022 走看看