火车票上的星号暗藏玄机

代码来源http://www.freebuf.com/articles/database/143402.html评论区中神奇的python代码

import time
s="3401021992****0428"
print [s.replace('****',j[4:])

for j in [time.strftime('%Y%m%d',time.localtime(i))

for i in range(int(time.mktime(time.strptime(s[6:10]+'0101','%Y%m%d'))),int(time.mktime(time.strptime(s[6:10]+'1231','%Y%m%d')))+1,3600*24)] if s[-1] == '10X98765432'[sum(map(lambda x: int(x[0]) * x[1], zip(s.replace('****',j[4:]), [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]) )) % 11]]

怎么理解上面这一段呢?花了好久才看懂,把每个步骤都拆开,记录一下

#coding=utf-8
import time
yearbegin=time.strptime('1992'+'0101','%Y%m%d')
yearend=time.strptime('1992'+'1231','%Y%m%d')
#mktime为用秒数表示的时间浮点值
yearbeginsec=time.mktime(yearbegin)
yearendsec=time.mktime(yearend)
#转换为int型,再用range创建数字列表表示这一年的X天
yearbeginint=int(yearbeginsec)
yearendint=int(yearendsec)
days=range(yearbeginint,yearendint+1,3600*24)
print len(days)
#上面的len为366说明数量没问题,1992年366天
#localtime转换为结构化时间,形如time.struct_time(tm_year=1992, tm_mon=12, tm_mday=24, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=359, tm_isdst=0)
structdays=[]
for someday in days:
	someday=time.localtime(someday)
	structdays.append(someday)
#将结构化的时间都转为%Y%m%d格式的时间,最终以列表的形式展示
formated_days=[]
for structday in structdays:
	formated_day=time.strftime('%Y%m%d',structday)
	formated_days.append(formated_day)
print formated_days
#校验身份证号码,筛选出符合校验位的几种可能结果
idcard='3408021992****0428'
for formated_day in formated_days:
	#求和,对11取模,通过模得到的校验码如果与idcard最后一位相同,就打印该formated_day
	zipx=zip(idcard.replace('****',formated_day[4:]),[7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2])
	summation=sum(map(lambda x:int(x[0])*x[1],zipx))
	mod_eleven=summation%11
	if '10X98765432'[mod_eleven]==idcard[-1]:
		print formated_day


步骤1:

遍历一年365天,使用time.strptime,time.mktime,time.strftime

(1)s[6:10]为1992

time.strptime()得到结构化的time:

time.struct_time(tm_year=1992, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=1, tm_isdst=-1)

time.struct_time(tm_year=1992, tm_mon=12, tm_mday=31, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=366, tm_isdst=-1)

(2)time.mktime()得到用秒数表示的时间浮点数:694195200.0和725731200.0

(3)int()将上面两个浮点数转为int型694195200和725731200

(4)range(参数A,参数B,参数C)表示从A到B(不包含B),间隔C,这里就是从694195200到725731200,间隔是3600*24,即每天打印一个数

(5)time.localtime()得到结构化time,如

time.struct_time(tm_year=1992, tm_mon=12, tm_mday=24, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=359, tm_isdst=0)

(6)time.strftime(format,上面的结构化time) 得到format格式的time,如19921224

至此,一年365天遍历完成


为什么要格式化时间---结构化---浮点型秒数---结构化---格式化时间,就是为了遍历365/366天


步骤2:

将365天的后4位填充到身份证中****的几位,通过校验位的生成方式,对比前面17位得到的校验位是否与实际校验位一直,过滤掉肯定错误的身份证号码




步骤3:数据验证

步骤2中我们得到的身份证号还有30多个,需要通过某些身份校验的接口(传入姓名+身份证)校验。接口很多,如:

https://market.aliyun.com/products/57000002/cmapi016424.html?spm=5176.730005.0.0.DX6osD#sku=yuncode1042400000

1分钱查询1条数据,一个身份证号最多需要0.3+才能查询到

猜你喜欢

转载自blog.csdn.net/waiwai3/article/details/78042272