-
从火车票提取完整实名信息
这里所说的完整的实名信息,包含姓名和身份证号码。从身份证号码可以知道籍贯、出生年月、性别。当然,进入相关数据库后,可以知道的东西就更多了。
网络上很多地方都在稀里哗啦地泄露着各个中国公民的真实姓名与身份证号码的配套信息,甚至包括相关照片。这个……在这里就不讨论了,就此打住。
这篇文章想说的是,从火车票中提取完整实名信息是多么的容易。
1、被隐藏的4位身份证号码
以前的实名制火车票是不会隐藏身份证号码的,全部打印在票面上。如下图:
后来,似乎觉得这样显示身份证信息不好,于是就隐去其中的4位。但是,加上了旅客的真实姓名。如下图:
2、恢复被隐藏的4位
在这里,我先介绍一下身份证的格式。
现在的身份证为18位,前6位为地址码,如上图中的370112是山东省历城区。后跟着8位日期码,如上图中的1981****,表明身份证的主人是1981年的某月某日出生的。其中的月和日被“*”隐去。后面的两位是顺序号编码,即00。接着以为性别码,即1。最后的一位是校验码,算法如下:
S = Ai * Wi, i = 2, ... , 18
Y = mod(S, 11)
i: 表示号码字符从右至左包括校验码字符在内的位置序号
Ai:表示第i位置上的身份证号码字符值
Wi:表示第i位置上的加权因子
i: 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 1可见被隐藏的4位信息,是身份证持有人的生日中的月份和日期。每年有多少天?最多366天。这下明白我的意思没?也就是说,我们只需要枚举最多366次,就可以将隐藏的信息还原,得到真实的身份证信息。而这366次枚举,还必须满足一个条件——前17位计算得到验证码必须和第18位得到的验证码匹配。
到了这里,我们还需要考虑另一个问题,在这366次枚举中,匹配的概率是多少?我没有认真计算匹配的概率,但假设得到的验证码的概率为平均分布的情况下,366次尝试得到的可能结果为:366*(1/11)=33.3。
我们使用下面的程序进行枚举:
#include <iostream> using namespace std; int days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int nums[20]; bool verifyID(int nums[]) { int iS = 0; int iW[]={0, 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; int verCode[] = {1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2}; int i; for(i=1;i<=17;i++) { iS += nums[i]* iW[i]; } int iY = iS%11; if(nums[18]==verCode[iY]) { return true; } else { return false; } } void printNum(int nums[]) { int i; for(i=1;i<=17;i++) { printf("%d", nums[i]); } (nums[18]==10)?(printf("X")):(printf("%d",nums[18])); printf("\n"); } int main() { int i,j; int year,count; char buf[128],buf2[2]; printf("前六位地区码:"); scanf("%s",buf); nums[1]=buf[0]-'0'; nums[2]=buf[1]-'0'; nums[3]=buf[2]-'0'; nums[4]=buf[3]-'0'; nums[5]=buf[4]-'0'; nums[6]=buf[5]-'0'; printf("年份:""); scanf("%s",buf); nums[7]=buf[0]-'0'; nums[8]=buf[1]-'0'; nums[9]=buf[2]-'0'; nums[10]=buf[3]-'0'; year=nums[7]*1000+nums[8]*100+nums[9]*10+nums[10]; if(year%400==0 || (year%400!=0 && year%4==0))//闰¨¨°年¨o { days[2]=29; } else { days[2]=28; } printf("最后四位:"); scanf("%s",buf); nums[15]=buf[0]-'0'; nums[16]=buf[1]-'0'; nums[17]=buf[2]-'0'; nums[18]=(buf[3]=='x' || buf[4]=='X')?10:(buf[3]-'0'); count=0; for(i=1;i<=12;i++) { for(j=1;j<=days[i];j++) { nums[11]=i/10; nums[12]=i%10; nums[13]=j/10; nums[14]=j%10; if(verifyID(nums)) { printNum(nums); count++; } } } printf("共%d个结果\n", count); //system("pause"); return 0; }
运行结果如下:
前六位地区码:370112
年份:1981最后四位:0010
70112198101020010
70112198101100010
70112198101290010
70112198102090010
70112198102170010
70112198102250010
70112198103050010
70112198103130010
70112198103210010
70112198104010010
70112198104280010
70112198105080010
70112198105160010
70112198105240010
70112198106040010
70112198106120010
70112198106200010
70112198107190010
70112198107270010
70112198108070010
70112198108150010
70112198108230010
70112198108310010
70112198109030010
70112198109110010
70112198110090010
70112198110170010
70112198110250010
70112198111050010
70112198111130010
70112198111210010
70112198112010010
70112198112280010
共33个结果
3、更方便得到身份证号码的方法
以下面的车票为例。
车票上的身份证号码部分的信息被PS了很多哦。
但是,我们扫描一下右边的二维码,得到:
480176011454143443488249648788273804579014484911756460444584907044800460033197910200023053897628805389762880538976288053897628805389762880820000
是的,里面的某部分内容就是被PS被“*”掉的身份证号码。
4、批量高技术方案
12306,不解释。
5、总结
个人别凑热闹晒车票,晒前也拜托好好打个马赛克,重分打个马赛克。还有,某些垄断组织好歹加强一下安全措施。
本文点到即止,仅作学习交流用途。
不多说了,就这些。
《从火车票提取完整实名信息》已有 14 条评论
最新文章
- EarthLiveSharp中cloudinary的CDN图片缓存自动清理
- WordPress取消英文标点符号自动替换中文标点符号的优雅方法
- 安装aria2及使用yaaw配置WebGUI界面
- Zabbix安装简记
- WordPress垃圾评论大作战
最近评论
- 湖南科大又一命案·一死两伤·汇总·湖南科技大学》 发表在《
- 湖南科大又一命案·一死两伤·汇总·湖南科技大学》 发表在《
- 湖南科大又一命案·一死两伤·汇总·湖南科技大学》 发表在《
- 湖南科大又一命案·一死两伤·汇总·湖南科技大学》 发表在《
- 湖南科大又一命案·一死两伤·汇总·湖南科技大学》 发表在《
标签云
Apache
CCTV
CentOS
Google
JAVA
Linux
MySQL
PHP
PHPmyadmin
rewrite
SSH
StatusNet
wordpress
YY
下载
中国
使用
剧情
动漫
动漫补完计划
动画
博客
域名
安装
影评
恭贺2010
方法
日本
服务器
柯南
死亡笔记
游戏
电影
第10放映室
网站
网络
翻译
腾讯
观后感
规则
视频
解决
设置
评论
配置