头图:https://cdn.naraku.cn/imgs/Python_id-cards0.jpg
最近突发奇想,想写一个小脚本来生成一个身份证后6位的小字典。因为学校有时候会发布的一些统一的账号表,例如校园网的账号密码,通常账号名为学号,密码则为身份证后6位,所以有时候可能会派上用场?
首先需要了解一下身份证号码结构:
1~6,地址码,常住户口所在地的行政区划代码7~14,出生年月日15~17,顺序码,且第17位由性别决定。男性为奇数,女性为偶数18校验码,将前面17位代入公式计算,结果为0~10,若为10则用X表示
举例:440106 19990101 0010
44广东省,01广州市,06天河区19990101,出生年月日001,第17位为1即男性0,最后一位为校验码
如果需要爆破后6位,即身份证的第13~18位,那么就有10*10*10*10*10*11(最后一位有0~X共11位)种可能
- 后6位中的第1位,即出生日期的十位,只能为
0~3,即4*10*10*10*10*11 - 而如果是针对某人而写的字典,知道目标的性别,那么第
5位就可以减掉一半。男性为1/3/5/7/9,女性为0/2/4/6/8,即4*10*10*10*5*11 - 同时,如果知道目标的出生日期(学校发的很多信息表中都会包含出生年月日等信息),即第
1~2位也可以确定了。那么需要爆破的只有15~18位,即10*10*5*11=5500,这个数量级已经对于电脑来说很轻松就可以完成。 
说了这么一大堆,其实最后也就10多行代码:
import itertoolsif __name__ == '__main__':date = input("出生日期: ")sex = '02468' if int(input("性别(男1女2): ")) % 2 == 0 else '13579' # 性别位check = '0123456789X' # 校验位other = '0123456789' # 其它位nums = itertools.product(other, other, sex, check)cards = []for num in nums:card = date + "".join(num)cards.append(card)print(len(cards))print(cards)

