火车票身份证号4位打码安全吗?
科普居民身份证号的生成和计算方式。
如果看上面这个太抽象,那么如下方式让你明白
身份证号码作为独一无二代表公民信息的号码,它的组成是由一下的数字表示的:
(1)第1、2位数字表示:所在省(直辖市、自治区)的代码;
(2)第3、4位数字表示:所在地级市(自治州)的代码;
(3)第5、6位数字表示:所在区(县、自治县、县级市)的代码;
(4)第7—14位数字表示:出生年、月、日;
(5)第15、16位数字表示:所在地的派出所的代码;
(6)第17位数字表示性别:奇数表示男性,偶数表示女性;
(7)第18位数字是校检码:是根据《中华人民共和国国家标准GB 11643-1999》中有关公民身份号码的规定,根据精密的计算公式计算出来的。校验码的计算方法:
1、将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7、9、10、5、8、4、2、1、6、3、7、9、10、5、8、4、2 ;
2、将这17位数字和系数相乘的结果相加;
3、用加出来和除以11,看余数是多少;
4、余数只可能有0、1、2、3、4、5、6、7、8、9、10这11个数字。其分别对应的最后一位身份证的号码为1、0、X、9、8、7、6、5、4、3、2,其中的X是罗马数字10;
5、通过上面得知如果余数是2,就会在身份证的第18位数字上出现罗马数字的Ⅹ;如果余数是10,身份证的最后一位号码就是2。
我现在就按照上述给算一下末尾这个数字是不是正确的。
610328199612201530这是一个正确的身份证号
我现在按照上述的方式计算一下最后一位这个校验位
7*6+9*1+10*0+5*3+8*2+4*8+2*1+1*9+6*9+3*6+7*1+9*2+10*2+5*0+8*1+4*5+2*3=276
276/11=25---1
余数为1,有上述第四条可知,余数1对应的最后一位应该是0。
网上找一个车票信息(不是我本人的),如侵权,请联系我删除
找了一个特殊的末尾是X,即代表10.
原理:
利用上述的机制,遍历该年(身份证上的年)的所有日期,看是否符合上述的规则,然后就可以删选出符合要求的,大大减少的域范围。本来是365天即365个,现在就只有几十个。
而且上述的规则,python中有一个库,可以直接校验是否正确,from id_validator import validator
validator.is_valid(“身份证号”)符合返回True,不符合返回False.
导包pip install validator
代码:
from id_validator import validator
import datetime
date_list = [] # 存储当年的所有日期信息
def create_assist_date(datestart, dateend):
datestart = datetime.datetime.strptime(datestart, '%Y-%m-%d')
dateend = datetime.datetime.strptime(dateend, '%Y-%m-%d')
date_list.append(datestart.strftime('%Y%m%d'))
while datestart < dateend:
# 日期叠加一天
datestart += datetime.timedelta(days=+1)
# 日期转字符串存入列表
date_list.append(datestart.strftime('%Y%m%d'))
def vali_dator1(id1, id3):
num = 0
for i in date_list:
theid = id1 + i + id3
if validator.is_valid(theid):#接口判断身份证是否符合规范
num = num + 1
print(theid)
# 统计符合要求的个数
return num
def vali_dator(id1, id2, id3):
create_assist_date(id2 + "-01-01", id2 + "-12-31")
num = vali_dator1(id1, id3)
print("共有" + str(num) + "个符合身份证号要求")
if __name__ == '__main__':
# 6123281997****3815
print("根据车票信息推断身份证号。")
a = input("输入前六位,比如610328\n")
if len(a)!=6:
exit("输入有误")
b = input("输入出生年,比如1996\n")
if len(b)!=4:
exit("输入有误")
c = input("输入后四位,比如1530\n")
if len(c)!=4:
exit("输入有误")
vali_dator(a, b, c)
结果:
根据车票信息推断身份证号。
输入前六位,比如610328
654127
输入出生年,比如1996
1990
输入后四位,比如1530
154x
65412719900107154x
65412719900115154x
65412719900123154x
65412719900131154x
65412719900203154x
65412719900211154x
65412719900318154x
65412719900326154x
65412719900406154x
65412719900414154x
65412719900422154x
65412719900430154x
65412719900502154x
65412719900510154x
65412719900529154x
65412719900609154x
65412719900617154x
65412719900625154x
65412719900705154x
65412719900713154x
65412719900721154x
65412719900801154x
65412719900828154x
65412719900908154x
65412719900916154x
65412719900924154x
65412719901003154x
65412719901011154x
65412719901118154x
65412719901126154x
65412719901206154x
65412719901214154x
65412719901222154x
65412719901230154x
共有34个符合身份证号要求
然后证明着34个中有一个会与之 名字(田慧敏) 相对应。利用12306的身份录入机制,将此34个与名字,录入,若录入成功则证明姓名与身份证号相互对应。
参考https://blog.csdn.net/lantian_123/article/details/102739831