• Impossible Codification


    在iq的blog上看到这样一段代码:

    int t[] = {0x4845A956, 0x586DEE32, 0x7E6B9933, 0x0D059D58, 0};
    int ch = t[0] + t[1] + t[2] + t[3];
    t[0]^=ch;
    t[1]^=ch;
    t[2]^=ch;
    t[3]^=ch;
    char *str = (char*)t;

    把str打印出来是这样的:Egad! It WORKS!!

    而如果将t的改为这样:

    int t[] = {0x151ba3a, 0x10abc1a, 0x118a113, 0x1e08bc0b, 0 };

    那么此时str为: Hi, how are you?.

    看起来很神奇吧。下面就来的推导一下怎么设置t的值,以使得str为任意字符串.

    令 x = t[0], y = t[1], z = t[2], w = t[3]

    我们需要将x, y, z, w经过指定的变换之后得到指定的x’, y’, z’, w’. 变换的过程为:

    s = x + y + z + w

    x’ = x ^ s

    y’ = y ^ s

    z’ = z ^ s

    w’ = w ^ s

    现在是已知x’, y’, z’, w’, 要求x, y, z, w.  这看起来有点麻烦,因为有4个未知数,但稍稍变换一下可以发现,实际上只需要求一个未知数 s 就够了. 将上面的后四式两边同时异或一个s, 得:

    x = x’ ^ s;     y = y’ ^ s;    z = z’ ^ s;    w = w’ ^ s.

    于是有方程:

    s = (x’^ s) + (y’ ^s) + (z’ ^s) + (w’^s)

    选定任意一个初始值,进行不动点迭代即可解得 s.

    这里有两个疑问,一是方程的解是否存在,二是上面的迭代是否一定会收敛。答案都是肯定的,也很好证明。对于存在性可以得到,若方程右边和式的项数是偶数(在上面是4项),则一定有解。而至于收敛性,因为一旦s的低位确定了,在迭代就不会变化了,而每次迭代至少会确定一个新的位,所于至多32次迭代就会收敛到解。感兴趣的同学可以自己推一下。

    好了,现在我们也可以构造出神秘的编码了,试试下面这个:

    int t[10] = {0x33106d0f, 0x3351230e, 0x66457026, 0x3f526130,0x7e1b4d67, 0x7a487767, 0x721c682b, 0x764a6d2b, 0x133c0469, 0x133c0447};
    int ch = 0;
    for (int i = 0; i != 10; ++i) ch += t[i];
    for (int i = 0; i != 10; ++i) t[i] ^= ch;
    char *str = (char*)t;
    printf(str);
  • 相关阅读:
    解决html中刷新页面后checkbox还选中的问题
    初始化spring容器的几种方法
    在web.xml中配置spring配置文件的路径
    查找算法
    排序算法
    ORACLE TO_CHAR,TO_DATE函数格式说明
    ORACLE TO_DATE函数
    ORACLE SUBSTR函数
    ORACLE学习笔记
    Linux 查看端口占用情况
  • 原文地址:https://www.cnblogs.com/atyuwen/p/impossible_codification.html
Copyright © 2020-2023  润新知