[求解] 比较刁钻的算法

2014-02-06 13:04:51 +08:00
 di1ji
求解a、b和结果三者之间的算法或规则
a=qWaYmA,,b=6
a=qWeYmA,,b=7
a=qWJhmw,,b=21
a=qWJomw,,b=28
a=qWZkmw,,b=64
a=qWZlmw,,b=65
a=qWZmmw,,b=66
a=qWZpmw,,b=69
a=qWdmmw,,b=76
a=qWhjmw,,b=83
a=qWlnmw,,b=97
结果=6003

a=qWWYmQ,,b=5
a=qWaYmQ,,b=6
a=qWFinA,,b=12
a=qWFknA,,b=14
a=qWJjnA,,b=23
a=qWJnnA,,b=27
a=qWNjnA,,b=33
a=qWNpnA,,b=39
a=qWRlnA,,b=45
a=qWRonA,,b=48
a=qWVlnA,,b=55
a=qWdjnA,,b=73
a=qWdonA,,b=78
a=qWlgnA,,b=90
a=qWlhnA,,b=91
a=qWVonA,,b=58
结果=6004

a=qWWYmg,,b=5
a=qWaYmg,,b=6
a=qWJjnQ,,b=23
a=qWNgnQ,,b=30
a=qWNmnQ,,b=36
a=qWRpnQ,,b=49
a=qWVhnQ,,b=51
a=qWVonQ,,b=58
a=qWdjnQ,,b=73
a=qWhlnQ,,b=85
结果=6005

算法(规则)是别人用php写的,我研究了几天解不出来,大家可以看看哦。
求解a、b和结果三者之间的算法或规则,解出来还有100元新年红包哦。
我写了个辅助验证器:http://www.ipdizhi.com/ss1.php
4732 次点击
所在节点    程序员
15 条回复
Lax
2014-02-06 13:32:35 +08:00
这是什么语法?
zhujinliang
2014-02-06 15:30:44 +08:00
不会贴代码。。。

玩了1个半小时。。猜测是以下过程,不过不能解释b=0或1时的输出。

<?php

$a = 'qWxlnZY';
$b = '75';

$str = base64_decode($a); // 对a进行base64解码

$str[0] = chr(ord($str[0]) - 115); // 第一位ASCII码减去 115

$b = strval(intval($b)); // 对b只取有效数字部分
$j = 0;
$magic_number = array(104, 101, 114, 111, 112, 97, 115, 115, 52);
$str_length = strlen($str);
for($i = 1; $i < $str_length; $i++) // 从第二位开始循环处理
{

$b_chr = ord($b[$i-1]);
if($b_chr)
{
$str[$i] = chr(ord($str[$i]) - $b_chr); // 如果对应位b有相应的值,则减去其ascii码值
}
else
{
$str[$i] = chr(ord($str[$i]) - $magic_number[($j++) % 9]); // 否则从一个幻数表里循环取值并减去
}
}

echo $str;
zhujinliang
2014-02-06 15:33:21 +08:00
zhujinliang
2014-02-06 15:35:50 +08:00
dingyaguang117
2014-02-06 15:36:38 +08:00
我去,大神这么多,我最近也遇到一个解密不了的,我发来大家一起看看
di1ji
2014-02-07 09:22:16 +08:00
@zhujinliang 大神啊,亲私信我你的支付宝账号,给亲个新年红包表示感谢。
di1ji
2014-02-07 09:24:19 +08:00
@zhujinliang 亲说的完全正确哦,他这个算法b不能等于0或1。
di1ji
2014-02-07 09:41:24 +08:00
@zhujinliang 不好意思,貌似v2ex没有私信,亲回帖告诉我吧,或发支付宝账号到我的邮箱5 0 4 0 5 6 0 7 8 @ qq . com
bojieyang
2014-02-07 15:44:28 +08:00
@zhujinliang 能说下你解的思路吗,我很好奇....
zhujinliang
2014-02-07 18:36:44 +08:00
@bojieyang

比较迷惑的是b与结果的值都是数字,我先在楼主给的验证器里随便改了改b的值,发现结果某一位发生了变化,而且变化比较有规律,甚至出现了非数字的符号,对照ASCII表,猜测是对对应字节进行加减上的运算,基本否定是将b及结果看做数值进行的运算。

首先看a,感觉就是base64编码后的,一般用于字符串编码的方式不是很多,base64很典型

然后先对a进行base64解码,方便分析。对于a解码后的结果,几乎都落在非ASCII字符区域,直接看解码结果没法看,我是逐字节用ord函数转成10进制看的。

仅看第一组,抽取几个a的值,分别base64解码,把结果都列出来,隐约就可发现规律:
1. 第一字节都相同
2. 第二字节不相同,之后的字节都相同
3. 第二字节的差值与b有关系
4. a的长度等于结果长度

再抽取一组b为两位的,同样base64解码,列出结果进行对比
1. 第一字节都相同
2. 第二字节与第三字节不同,之后的都相同,
3. 第二、三字节,每字节的差值与b关

此时可得到一些规律:
1. 第一字节是固定处理的,与b无关
2. 之后的字节与b有关,基本是逐字节对应处理的

基本看得出整个处理的尿性就是相减,之后就是找几个位数比较长的a与结果互相加减,找规律。

由于楼主提供了一个验证器页面,大致找到一些规律后,就可以自己构造a与b的值,代入验证器进行实验。后面那个幻数表就是我构造了一个很长的a的值,代入验证器后,发现后面的结果是循环的,基本就可以认定是循环取的幻数进行操作的了,然后对照ASCII码表算出幻数。
di1ji
2014-02-07 21:02:52 +08:00
@zhujinliang 亲红包已经发送哦,谢谢~~
能帮我逆写下一个根据结果(比如6005)算出a和b的php代码不。
zhujinliang
2014-02-07 22:31:35 +08:00
@di1ji
谢谢你~!红包已收到,比一开始说的100还翻了一番,真是又惊喜又不知所措。。。

感觉红包受之有愧,根据之前推的算法,写了个比较完整的代码供实验
https://gist.github.com/8863454
di1ji
2014-02-07 23:05:02 +08:00
@zhujinliang
看来我要好好学习php了,为什么亲这样的高手写代码都那么简洁给力呢。
谢谢亲新年的努力和恭喜破解了这么刁钻的算法哦^_^。
zhujinliang
2014-02-07 23:33:07 +08:00
改正一处错误
if($chr == $magic_number[$number_index++]) continue;
应该是
if($chr == $magic_number[($number_index++) % 9]) continue;


楼主太客气了~~
tpu01yzx
2014-02-20 01:55:57 +08:00
经测试有以下规律:
-999999999<=a<=48991时,无论b取何值,结果都是A,
@zhujinliang 给的代码无法通过这个测试:
a=-999999999,b=2,
楼主给的验证器输出为:-999999999
而你的代码输出为:�� �m
那是不是所有base64解码失败都会原样输出呢?我觉得@zhujinliang 可以做进一步的测试。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/99120

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX