假设我有一个长度为32的Java字符串,例如
String s = "Y7yEdfjQ2qmpGZbPYswKIdxYVo6KnR9M";
我正在寻找具有以下属性的字符串t:如果在t上执行以下循环,则生成的字符串为s :
char[] tArr = t.toCharArray();
for (int i = 1; i < 32; i++) {
tArr[i] = (char) (tArr[i] ^ tArr[i * 123456 % 31] & 31);
}
请注意,在Java中,数组运算符[]具有最高优先级,并且在按位异或之前计算按位AND。
为了获得t,必须对s应用反向操作。 XOR的逆运算是异或,但逻辑AND显然没有逆运算。
字符串t可以在没有强制执行的情况下恢复吗?
答案 0 :(得分:3)
31是11111b
因此该算法占用任何char的最低5位,这使您无法恢复初始字符串 - 您可能会发现一些字符串导致相同的散列
而蛮力是这里唯一的选择
答案 1 :(得分:3)
你的循环在每次迭代中接受两个字符,并且xors第一个字符与另一个字符的最低5位。这意味着前3位保持不变。他们不会迷路。事实上,t[i]
的前3位等于s[i]
的前3位,我们只需找到原始字符串t
中字符的最低5位。
现在,让我们计算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
xor双方,并得到:
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
哪里?????是t[30]
的最低5位,xxxxx是t[17]
的最低5位。但实际上,它不是原来的t[17]
。当我们分配t[30]
时,t[17]
已经更新为其最终值,我们知道(它是s[17]
- 's'或01110011
)。
因此001 11001 = 001 ????? ^ 000 10011
。
如果我们xor双方,001 11001 ^ 000 10011 = 001 01010
所以原来的t[30]
是00101010。
到目前为止,我找到了t[0]
,t[30]
和t[31]
。
我相信(虽然我实际上没有检查过),我可以继续以这种方式找到t
的所有其他角色。
在我们计算t[i]
时要注意的重要一点是,如果t[i]
取决于t[j]
,i<j
,则取决于{{{1}的原始值1}}(未知),而如果t[j]
,则取决于i>j
的最终值(t[j]
- 我们知道)。