15015613

火车票身份证号的打码真不靠谱!

  •  
  •   15015613 · Jan 18, 2017 · 5620 views
    This topic created in 3575 days ago, the information mentioned may be changed or developed.

    今天坐火车,发现火车票上的身份证号仅仅把出生月日这四位打了码,满打满算不超过 400 种可能性。
    另外,最后一位校验码也没有打码,感觉又可以排除不少。

    回来简单写了个脚本,验证了一下。发现加上校验码,最终只有不超过 40 种可能性(试了好几个身份证号)。
    这码打的,跟没打差不多了。

    附上代码:

    #!/usr/bin/env python3
    # -*- encoding: utf-8 -*-
    
    def ID_number_check(num_in):
        if len(num_in) != 18:
            return False
        try:
            int(num_in[:17])
        except:
            return False
        check_num=num_in[-1]
        total_sum=int(num_in[0])*7+int(num_in[1])*9+int(num_in[2])*10+int(num_in[3])*5+int(num_in[4])*8+int(num_in[5])*4+int(num_in[6])*2+int(num_in[7])*1+int(num_in[8])*6+int(num_in[9])*3+int(num_in[10])*7+int(num_in[11])*9+int(num_in[12])*10+int(num_in[13])*5+int(num_in[14])*8+int(num_in[15])*4+int(num_in[16])*2
        remain=total_sum%11
        if remain == 0:
            check=1
        elif remain == 1:
            check=0
        elif remain == 2:
            check='X'
        elif remain == 3:
            check=9
        elif remain == 4:
            check=8
        elif remain == 5:
            check=7
        elif remain == 6:
            check=6
        elif remain == 7:
            check=5
        elif remain == 8:
            check=4
        elif remain == 9:
            check=3
        elif remain == 10:
            check=2
        if str(check_num) == str(check):
            return True
        else:
            return False
    
    def ID_number_guess(num_in):
        num_in=num_in.upper()
        if len(num_in) != 18:
            print('请输入 18 位身份证号')
            exit(1)
        part1=num_in[:10]
        part2=num_in[-4:]
        year=num_in[6:10]
        Mons=range(1, 13)
        for Mon in Mons:
            if Mon in [1, 3, 5, 7, 8, 10, 12]:
                Days=range(1, 32)
            elif Mon == 2 and leap_year_check(year):
                Days=range(1, 30)
            elif Mon == 2 and not leap_year_check(year):
                Days=range(1, 29)
            else:
                Days=range(1, 31)
            if len(str(Mon)) == 1:
                Mon='0' +str(Mon)
            for Day in Days:
                if len(str(Day)) == 1:
                    Day='0' +str(Day)
                num_out=part1 +str(Mon) +str(Day) +part2
                if ID_number_check(num_out):
                    print(num_out)
    
    def leap_year_check(year):
        try:
            year=int(year)
        except:
            return False
        if year % 400 == 0:
            return True
        elif year % 100 != 0 and year % 4 == 0:
            return True
        else:
            return False
    
    if __name__ == '__main__':
        ID_number=input('请输入要猜测的身份证号: ')
        ID_number_guess(ID_number)
    
    11 replies  •  2017-01-19 10:29:23 +08:00
    15015613
    15015613
    OP
    Jan 18, 2017
    1
    效果(身份证号从网上随便找的):
    ```
    请输入要猜测的身份证号: 5301021920****011x
    53010219200102011X
    53010219200110011X
    53010219200129011X
    53010219200209011X
    53010219200217011X
    53010219200225011X
    53010219200305011X
    53010219200313011X
    53010219200321011X
    53010219200401011X
    53010219200428011X
    53010219200508011X
    53010219200516011X
    53010219200524011X
    53010219200604011X
    53010219200612011X
    53010219200620011X
    53010219200719011X
    53010219200727011X
    53010219200807011X
    53010219200815011X
    53010219200823011X
    53010219200831011X
    53010219200903011X
    53010219200911011X
    53010219201009011X
    53010219201017011X
    53010219201025011X
    53010219201105011X
    53010219201113011X
    53010219201121011X
    53010219201201011X
    53010219201228011X
    ```
    qceytzn
    qceytzn
    Jan 18, 2017
    2
    楼主,代码怎么用??(我不是程序员)
    http://imgur.com/EUguxRZ
    fish267
    fish267
    Jan 18, 2017 via Android
    3
    哦
    qceytzn
    qceytzn
    Jan 18, 2017
    4
    哦。知道了
    goodbest
    goodbest
    Jan 18, 2017❤️1
    5
    让我来 code review 一下:

    那一堆 if else 可以考虑改成 dict ,或者直接以 remain 值作为索引的 list 也行。

    既然是日期类的变量,变量 Mon 可能会与 Monday 混淆,因此可以考虑将其改掉。
    ming2050
    ming2050
    Jan 18, 2017 via iPhone
    6
    其实已经算是靠谱了
    HannibaI
    HannibaI
    Jan 18, 2017
    7
    一堆的 if else 看着好难受
    15015613
    15015613
    OP
    Jan 18, 2017
    8
    @goodbest
    受教了
    zhujinliang
    zhujinliang
    Jan 18, 2017
    9
    无校验码约 400 种可能,校验码一共有 11 种可能,加上校验码不就大约 400/11 种可能么。。。
    superbear
    superbear
    Jan 18, 2017
    10
    再结合年份范围,又排除不少
    Vizogood
    Vizogood
    Jan 19, 2017
    11
    @qceytzn python 3 用 Linux 或 Mac 或 Windows+python
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1382 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 20:15 · PVG 04:15 · LAX 12:15 · JFK 15:15
    ♥ Do have faith in what you're doing.