头图: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多行代码:

    1. import itertools
    2. if __name__ == '__main__':
    3. date = input("出生日期: ")
    4. sex = '02468' if int(input("性别(男1女2): ")) % 2 == 0 else '13579' # 性别位
    5. check = '0123456789X' # 校验位
    6. other = '0123456789' # 其它位
    7. nums = itertools.product(other, other, sex, check)
    8. cards = []
    9. for num in nums:
    10. card = date + "".join(num)
    11. cards.append(card)
    12. print(len(cards))
    13. print(cards)

    Python - 生成身份证后6位字典 - 图1