我有等式:
C = A^b + (2*A)^b + (4*A)^b.
C和A已知,但b未知。怎么找到b? 所有数字都是8位字节。有没有比蛮力更快的方法?
答案 0 :(得分:0)
+符号是否表示字节和*乘法的加法,是否丢弃溢出位?如果是这样,我认为答案是
b = C ^ (A + 2 * A + 4* A)
如何得出这个结论:
C = A^b + (2*A)^b + (4*A)^b
因此
C^b = A^b^b + (2*A)^b^b + (4*A)^b^b = A + 2*A + 4*A
然后
C^C^b = b = C^(A + 2*A + 4*A)
编辑只是为了确保:这个答案不正确。对我感到羞耻。我需要多考虑一下。
答案 1 :(得分:0)
我采取了相同的假设:+
和*
是加法和乘法,忽略溢出。
这可能是最快的解决方案:预先计算结果,并将它们存储在查找表中。它需要2个 16 字节的内存,或64 kB。
以C系列式伪代码呈现:
byte Solve(byte a, byte c){
byte guess = lastGuess = result = lastResult = 0;
do {
guess = lastGuess ^ lastResult ^ c; //see explanation below
result = a^guess + (2*a)^guess + (4*a)^guess;
lastGuess = guess;
lastResult = result;
} while (result != c);
return guess;
}
这个算法的想法是它猜测b
是什么,然后将其插入公式中以获得暂定结果,并将其与c
进行对比。无论猜测中的哪些位导致结果与c
不同,都会发生变化。这对应于最后一次猜测的XOR,最后一次结果和c
(如果这个语句有点跳跃,我鼓励你绘制一个真值表,而不是仅仅接受我的话!)。
它的工作原理是因为改变一个位只能影响该位的结果,以及更重要的位,而不是更低的位(因为当你用笔和纸添加时,进位可以传播到左边)。因此,在最坏的情况下,算法需要2次猜测以获得最低有效位,第二次lsb的另一次猜测,第三次的另一次猜测,等等,对于最多9次猜测,给出任意组合{ {1}}和a
。
以下是我的测试程序的示例跟踪:
c