这回不定位女友了:火车票上的星号暗藏玄机?!

2017-08-08 399513人围观 ,发现 43 个不明物体 数据安全

本文原创作者:老汤&新撸(刀郎),本文属FreeBuf原创奖励计划,未经许可禁止转载

前言

随着网络的发展,现在人手一部手机,大家别误会啊,我不是在定位女友了(前文回顾点我),我只是感慨一下网路的发展快。昨天回了一次老家,在车上无聊看着火车票,虽然火车票上的身份证打了四个星号,但是是否意味着安全啦?

捕获.PNG

通过百度简单的搜索一下

点击我百度火车票搜索

详细分析

1.寻找数据源

我们随便选择一个

数据源

就这位了

2.四位星号分析

现在我们来分析一下这四位星号,从身份证的构造上看 肯定是 月日,二个字节表示月或者日,假如四个星号为(ABCD)

那么A 代表的是月 大家都知道月最多是12月 那么A 最大是1,

那么只有二种选择(0,1),

好现在我们开始判断一下B的取值范围:

当A为0的时候B取值为(1-9)

 当A为1的时候B取值为(0-2)

现在来判断C的范围,大家都知道一个月最多31天,

那么C的范围(0-3)

现在判断一下D的范围

当C为0的时候D为1-9

当C为1-2的时候D为0-9

当C为3的时候D为0-1

大家别嫌弃我分析麻烦,如果不分析,怎么写代码?

3.写代码生成数据

//月左位
for (size_t iA = 0; iA < 2; iA++)
{
//月右位
for (size_t iB = 0; iB < 10; iB++)
{
//当A为0的时候B取值为(1 - 9)
if (iA==0)
{
if (iB==0)
{

continue;
}
}
else if (iA == 1) //当A为1的时候B取值为(0-2)
{
if (iB > 2)
{
continue;
}
}

//日的左边
for (size_t iC = 0; iC < 4; iC++)
{

//日的右边
for (size_t iD = 0; iD < 10; iD++)
{
//当C为0的时候D为1-9
if (iC==0)
{
if (iD == 0)
{
continue;
}
}
else if (iC == 3)//当C为3的时候D为0 - 1
{
if (iD > 1)
{
continue;
}
}



sprintf(buffer, "%s%d%d%d%d%s", pFrist,iA, iB, iC, iD, pEnd);
if (!Chk18PaperId(buffer))
{
WriteFile(hFile, buffer, strlen(buffer), &dwWrite, NULL);
WriteFile(hFile, "\r\n", 2, &dwWrite, NULL);
}




}
}
}
}

写代码生成数据

4.数据进行过滤

根据月大月小过滤一下数据,1.3.5.7.8.10.12 是月大 2月只有28天

//开始遍历 //1 3 5 7 8 10 12 月大
//进行月大月小的判断

if (iA==0)
{
if (iB == 4 || iB == 6 || iB == 9 || iB == 11)
{
//月小
if (iC == 3 && iD == 1)
{
continue;
}
}
else if (iB==2)
{
//月小
if (iC > 2)
{
continue;
}
else if (iC==2&&(iD>8))
{
continue;
}
}

}
else
{
if (iB==1)
{
//11月是月小
if (iC==3&&iD==1)
{
continue;
}
}
}

数据进行过滤

少了几条啊

5.数据再次过滤

一共有三百多条数据,我们需要进一步进行过滤,过滤原理如下

校验规则是:

(1)十七位数字本体码加权求和公式 

S = Sum(Ai * Wi), i = 0, … , 16 ,先对前17位数字的权求和 

Ai:表示第i位置上的身份证号码数字值 

Wi:表示第i位置上的加权因子 

Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 

(2)计算模 

Y = mod(S, 11) 

(3)通过模得到对应的校验码 

Y: 0 1 2 3 4 5 6 7 8 9 10 

校验码: 1 0 X 9 8 7 6 5 4 3 2

int Chk18PaperId(const char *sPaperId)
{
long lSumQT = 0;
//加权因子  
int R[] = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
//校验码  
char sChecker[11] = { '1','0','X', '9', '8', '7', '6', '5', '4', '3', '2' };
//检验长度  
if (18 != strlen(sPaperId)) return -1;
//校验数字  
for (int i = 0; i<18; i++)
{
if (!isdigit(sPaperId[i]) && !(('X' == sPaperId[i] || 'x' == sPaperId[i]) && 17 == i))
{
return -1;
}
}
//验证最末的校验码  
for (int i = 0; i <= 16; i++)
{
lSumQT += (sPaperId[i] - 48) * R[i];
}
if (sChecker[lSumQT % 11] != sPaperId[17])
{
return -1;
}
return 0;
}

看计算后的结果

通过模得到对应的校验码

这个结果还是比较满意的,只有三十多次了

6.数据验证

最后一步,数据验证

数据验证

根据姓名和上传生成的30多个身份证id取验证一下吧

我随机选择了家的,代码如下 大同小异,关于最后身份证号码是多少?我在此保密,自己验证

数据验证

验证测试代码

#include<Windows.h>
#include<stdio.h>
/***************************************************
* 函 数 名: Chk18PaperId
*
* 函数功能: 校验18位身份证号码
*
* 输入参数:  sPaperId  身份证号
*
* 输出参数:
*
* 返回值:   0        成功
*           其他     失败
****************************************************/
int Chk18PaperId(const char *sPaperId)
{
long lSumQT = 0;
//加权因子  
int R[] = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
//校验码  
char sChecker[11] = { '1','0','X', '9', '8', '7', '6', '5', '4', '3', '2' };
//检验长度  
if (18 != strlen(sPaperId)) return -1;
//校验数字  
for (int i = 0; i<18; i++)
{
if (!isdigit(sPaperId[i]) && !(('X' == sPaperId[i] || 'x' == sPaperId[i]) && 17 == i))
{
return -1;
}
}
//验证最末的校验码  
for (int i = 0; i <= 16; i++)
{
lSumQT += (sPaperId[i] - 48) * R[i];
}
if (sChecker[lSumQT % 11] != sPaperId[17])
{
return -1;
}
return 0;
}
void CreateId(char * pFrist, char * pEnd)
{
char buffer[MAX_PATH] = { 0 };
DWORD dwWrite = 0;
HANDLE hFile = CreateFileA("1.txt", 
FILE_WRITE_ACCESS, NULL, 
NULL, OPEN_ALWAYS, NULL, NULL);
//月左位
for (size_t iA = 0; iA < 2; iA++)
{
//月右位
for (size_t iB = 0; iB < 10; iB++)
{
//当A为0的时候B取值为(1 - 9)
if (iA==0)
{
if (iB==0)
{

continue;
}
}
else if (iA == 1) //当A为1的时候B取值为(0-2)
{
if (iB > 2)
{
continue;
}
}

//日的左边
for (size_t iC = 0; iC < 4; iC++)
{

//日的右边
for (size_t iD = 0; iD < 10; iD++)
{
//当C为0的时候D为1-9
if (iC==0)
{
if (iD == 0)
{
continue;
}
}
else if (iC == 3)//当C为3的时候D为0 - 1
{
if (iD > 1)
{
continue;
}
}

//开始遍历 //1 3 5 7 8 10 12 月大
//进行月大月小的判断

if (iA==0)
{
if (iB == 4 || iB == 6 || iB == 9 || iB == 11)
{
//月小
if (iC == 3 && iD == 1)
{
continue;
}
}
else if (iB==2)
{
//月小
if (iC > 2)
{
continue;
}
else if (iC==2&&(iD>8))
{
continue;
}
}

}
else
{
if (iB==1)
{
//11月是月小
if (iC==3&&iD==1)
{
continue;
}
}
}

sprintf(buffer, "%s%d%d%d%d%s", pFrist,iA, iB, iC, iD, pEnd);
if (!Chk18PaperId(buffer))
{
WriteFile(hFile, buffer, strlen(buffer), &dwWrite, NULL);
WriteFile(hFile, "\r\n", 2, &dwWrite, NULL);
}




}
}
}
}
CloseHandle(hFile);
}
void main()
{

CreateId("2113241992", "3014");
}

最后总结

希望大家注意火车票的隐私,千万别乱丢火车票,同时提醒12306给校验码去掉,这样就增加了难度

本文原创作者:老汤&新撸(刀郎),本文属FreeBuf原创奖励计划,未经许可禁止转载

这些评论亮了

  • import time
    s="2113241992****3014"
    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]]

    ['211324199201043014', '211324199201123014', '211324199201203014', '211324199202193014', '211324199202273014', '211324199203073014', '211324199203153014', '211324199203233014', '211324199203313014', '211324199204033014', '211324199204113014', '211324199205183014', '211324199205263014', '211324199206063014', '211324199206143014', '211324199206223014', '211324199206303014', '211324199207023014', '211324199207103014', '211324199207293014', '211324199208093014', '211324199208173014', '211324199208253014', '211324199209053014', '211324199209133014', '211324199209213014', '211324199210193014', '211324199210273014', '211324199211073014', '211324199211153014', '211324199211233014', '211324199212033014', '211324199212113014']
    )60( 亮了
  • Magina (1级) 回复
    不去好好唱歌,怎么跑来研究代码了
    )20( 亮了
  • 其实一直不明白,原来一般都是隐藏后4位,什么时候脑残到把校验位放出来的
    )19( 亮了
  • freewill (2级) 自由星空、星夜无悔 回复
    @ linux404  Python大法好
    )18( 亮了
  • D14tr0y (3级) 这家伙太懒了,还未填写个人描述! 回复
    加权还有下面的模是干嘛的?
    )16( 亮了
发表评论

已有 43 条评论

取消
Loading...

特别推荐

关注我们 分享每日精选文章

css.php