V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
di1ji
V2EX  ›  程序员

[求解] 比较刁钻的算法

  •  
  •   di1ji · 2014-02-06 13:04:51 +08:00 · 4701 次点击
    这是一个创建于 3934 天前的主题,其中的信息可能已经有所发展或是发生改变。
    求解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
    15 条回复    1970-01-01 08:00:00 +08:00
    Lax
        1
    Lax  
       2014-02-06 13:32:35 +08:00
    这是什么语法?
    zhujinliang
        2
    zhujinliang  
       2014-02-06 15:30:44 +08:00   ❤️ 1
    不会贴代码。。。

    玩了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
        3
    zhujinliang  
       2014-02-06 15:33:21 +08:00
    zhujinliang
        4
    zhujinliang  
       2014-02-06 15:35:50 +08:00
    dingyaguang117
        5
    dingyaguang117  
       2014-02-06 15:36:38 +08:00
    我去,大神这么多,我最近也遇到一个解密不了的,我发来大家一起看看
    di1ji
        6
    di1ji  
    OP
       2014-02-07 09:22:16 +08:00
    @zhujinliang 大神啊,亲私信我你的支付宝账号,给亲个新年红包表示感谢。
    di1ji
        7
    di1ji  
    OP
       2014-02-07 09:24:19 +08:00
    @zhujinliang 亲说的完全正确哦,他这个算法b不能等于0或1。
    di1ji
        8
    di1ji  
    OP
       2014-02-07 09:41:24 +08:00
    @zhujinliang 不好意思,貌似v2ex没有私信,亲回帖告诉我吧,或发支付宝账号到我的邮箱5 0 4 0 5 6 0 7 8 @ qq . com
    bojieyang
        9
    bojieyang  
       2014-02-07 15:44:28 +08:00
    @zhujinliang 能说下你解的思路吗,我很好奇....
    zhujinliang
        10
    zhujinliang  
       2014-02-07 18:36:44 +08:00   ❤️ 1
    @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
        11
    di1ji  
    OP
       2014-02-07 21:02:52 +08:00
    @zhujinliang 亲红包已经发送哦,谢谢~~
    能帮我逆写下一个根据结果(比如6005)算出a和b的php代码不。
    zhujinliang
        12
    zhujinliang  
       2014-02-07 22:31:35 +08:00   ❤️ 1
    @di1ji
    谢谢你~!红包已收到,比一开始说的100还翻了一番,真是又惊喜又不知所措。。。

    感觉红包受之有愧,根据之前推的算法,写了个比较完整的代码供实验
    https://gist.github.com/8863454
    di1ji
        13
    di1ji  
    OP
       2014-02-07 23:05:02 +08:00
    @zhujinliang
    看来我要好好学习php了,为什么亲这样的高手写代码都那么简洁给力呢。
    谢谢亲新年的努力和恭喜破解了这么刁钻的算法哦^_^。
    zhujinliang
        14
    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
        15
    tpu01yzx  
       2014-02-20 01:55:57 +08:00
    经测试有以下规律:
    -999999999<=a<=48991时,无论b取何值,结果都是A,
    @zhujinliang 给的代码无法通过这个测试:
    a=-999999999,b=2,
    楼主给的验证器输出为:-999999999
    而你的代码输出为:�� �m
    那是不是所有base64解码失败都会原样输出呢?我觉得@zhujinliang 可以做进一步的测试。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3606 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 00:09 · PVG 08:09 · LAX 16:09 · JFK 19:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.