python实现身份证号生成器

最近开始接触金融相关的测试,发现在金融测试中身份证号是个很重要的数据,网上也有很多大佬自己写的身份证生成器,抱着学习的态度,花了两个晚上的时间用python写完了这个身份证号生成器

1. 身份证编码规则

1.1. 身份证地址码

共6位,表示登记户口时所在地的行政区划代码(省、市、县),如下:

1.2. 出生年月日

共8位,表示该居民的出生年月日,年4位数字,月和日分别用2位数字表示,如19930211

1.3. 顺序码

共3位,同一区域内同年同月同日生的人的顺序顺延,男生占偶数,女生占奇数,不足三位自动在前面补0,如某地区出生的第一位男生,则顺序码为002

1.4. 校验码

共1位,校验码前面17位为本体位,校验码根据本体位计算得到
1.4.1. 本体位每位和对应的加权因子相乘并求和得sum
1.4.2. sum对11取余
1.4.3. 根据余数和校验码对应表得到最后的校验码值

附:

举例:44180020130412122(不包含校验码)

  1. sum = 4x7 + 4x9 + 1x10 + 8x5 + 0x8 + 0x4 + 2x2 + 0x1 + 1x6 + 3x3 + 0x7 + 4x9 + 1x10 + 2x5 + 1x8 + 2x4 +2x2 = 209
  2. 对11取余得0
  3. 根据余数和校验码表得到对应值为1

tips:最后一位也可以根据m=12-sum%11得到,若x为10,则最后一位为X,否则为计算得到的m

2. python编码

2.1. 身份证地址码生成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
def getAddressNum(self, useRandom=True):
# 存储地址和地址码之间的对应
addressToNumber = json.load(open("function/json/addresstonumber.json", encoding="utf-8"))
# 随机生成一个地址码
if useRandom:
print("随机生成一个地址码.....")
tempAddress = random.sample(list(addressToNumber.keys()), 1)[0]
self.addressNum = addressToNumber[tempAddress]
return self.addressNum, tempAddress
# 根据用户提供的信息
else:
address = input("请输入省份或城市:\n")
tempList = []
if len(address) == 0:
return self.getAddressNum(useRandom=False)
for x in addressToNumber.keys():
if address in x:
tempList.append(x)
if len(tempList) == 0:
print("输入的省份或城市未找打,请确认!")
return self.getAddressNum(useRandom=False)
print("请选择对应的城市:")
for i in range(len(tempList)):
print(str(i) + "." + tempList[i])
num = input("请输入对应城市编号(默认则为随机选择以下任意一个城市):")
if len(num) == 0:
num = random.randint(0, len(tempList))
else:
num = int(num)
tempNumber = addressToNumber[tempList[num]]
self.addressNum = tempNumber
return tempNumber, tempList[int(num)]

2.2. 出生年月生成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def getBirthdayNum(self, useRandom=True):
# 随机生成一个年月日
if useRandom:
print("随机生成一个出生日期......")
startTime = int(time.mktime((1984, 1, 1, 0, 0, 0, 0, 0, 0)))
endTime = int(time.time())
x = random.randrange(startTime, endTime)
date_touple = time.localtime(x)
date = time.strftime("%Y%m%d", date_touple)
self.birthdayNum = date
return date
# 根据用户提供的信息
else:
birthday = input("请输8位生日(格式xxxxxxxx,如19930405):")
if len(birthday) == 0:
self.birthdayNum = self.getBirthdayNum()
return self.birthdayNum
elif len(birthday) != 8:
print("输入有误!")
self.birthdayNum = self.getBirthdayNum(useRandom=False)
return self.birthdayNum
else:
self.birthdayNum = birthday
return self.birthdayNum

2.3. 顺序码生成

1
2
3
4
5
6
7
8
9
10
11
def getOrder(self):
temp = random.randint(0, 999)
if temp < 10:
self.orderNum = '00' + str(temp)
return self.orderNum
elif temp < 100:
self.orderNum = '0' + str(temp)
return self.orderNum
else:
self.orderNum = str(temp)
return self.orderNum

2.4. 校验码生成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def getLastCode(self, top17=''):
# 加权因子
factorNumber = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
if len(top17) == 0:
temp = self.addressNum + self.birthdayNum + self.orderNum
else:
temp = top17
lastcodetemp = 0
for i, j in zip(factorNumber, temp):
lastcodetemp = lastcodetemp + i * int(j)
lastcodetemp = 12 - lastcodetemp
lastcode = 'X' if lastcodetemp % 11 == 10 else lastcodetemp % 11
self.lastCode = str(lastcode)
return lastcode

完整代码

投食