您的循环在每次迭代中接受两个字符,并将第一个字符与另一个字符的最低 5 位进行异或。这意味着前 3 位保持不变。他们不会迷路。实际上 的 前 3 位t[i]
等于 的 前 3 位s[i]
, 我们只需要找到原始字符串中字符的最低 5 位t
.
现在,让我们计算i * 123456 % 31
一下,看看循环在每次迭代中实际做了什么:
t[1] = t[1] ^ (t[14]&31)
t[2] = t[2] ^ (t[28]&31)
t[3] = t[3] ^ (t[11]&31)
t[4] = t[4] ^ (t[25]&31)
t[5] = t[5] ^ (t[8]&31)
t[6] = t[6] ^ (t[22]&31)
t[7] = t[7] ^ (t[5]&31)
t[8] = t[8] ^ (t[19]&31)
t[9] = t[9] ^ (t[2]&31)
t[10] = t[10] ^ (t[16]&31)
t[11] = t[11] ^ (t[30]&31)
t[12] = t[12] ^ (t[13]&31)
t[13] = t[13] ^ (t[27]&31)
t[14] = t[14] ^ (t[10]&31)
t[15] = t[15] ^ (t[24]&31)
t[16] = t[16] ^ (t[7]&31)
t[17] = t[17] ^ (t[21]&31)
t[18] = t[18] ^ (t[4]&31)
t[19] = t[19] ^ (t[18]&31)
t[20] = t[20] ^ (t[1]&31)
t[21] = t[21] ^ (t[15]&31)
t[22] = t[22] ^ (t[29]&31)
t[23] = t[23] ^ (t[12]&31)
t[24] = t[24] ^ (t[26]&31)
t[25] = t[25] ^ (t[9]&31)
t[26] = t[26] ^ (t[23]&31)
t[27] = t[27] ^ (t[6]&31)
t[28] = t[28] ^ (t[20]&31)
t[29] = t[29] ^ (t[3]&31)
t[30] = t[30] ^ (t[17]&31)
t[31] = t[31] ^ (t[0]&31)
我们知道,在最后一次迭代之后,数组已经从t
(我们不知道)转换为s
(我们知道 - “Y7yEdfjQ2qmpGZbPYswKIdxYVo6KnR9M”)。
现在,由于t[0]
从未修改,我们知道s[0]=t[0]='Y'
(或二进制的 01011001)。
这t[31]
很容易给我们:
t[0]&31 = 00011001
s[31] = 'M' = 01001101 = t[31] ^ 00011001
两边异或,得到:
t[31] = 01001101 ^ 00011001 = 01010100
其他角色不太容易。
循环的迭代形成两个循环:
1->14->10->16->7->5->8->19->18->4->25->9->2->28->20->1
3->11->30->17->21->15->24->26->23->12->13->27->6->22->29->3
现在,让我们尝试查找 的其他字符t
:
t[30] = t[30] ^ (t[17]&31)
在此分配之后,t[30]
变为s[30]
,即 '9' 或 00111001。
我们知道001 11001 = 001 ????? ^ 000 xxxxx
在哪里 ?????是 的最低 5 位,t[30]
xxxxxx 是 的最低 5 位t[17]
。但实际上,它不是原版的t[17]
。到我们分配的时候t[30]
,t[17]
已经更新到它的最终值,我们知道(它是s[17]
- 's' 或01110011
)。
因此001 11001 = 001 ????? ^ 000 10011
。
如果我们两边异或,001 11001 ^ 000 10011 = 001 01010
所以原来t[30]
是00101010。
到目前为止,我t[0]
发现t[30]
和t[31]
。我相信(虽然我还没有真正检查过),我可以继续以t
这种方式找到所有其他角色。
计算时要注意的重要一点t[i]
是,如果t[i]
依赖于t[j]
这样i<j
,它依赖于t[j]
(未知数)的原始值,而如果i>j
,它依赖于t[j]
(s[j]
即我们知道的)的最终值。