今天坐火车,发现火车票上的身份证号仅仅把出生月日这四位打了码,满打满算不超过 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)
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.