重建用逐位运算操作的字符串

时间:2014-07-02 19:09:18

标签: java bitwise-operators inverse bitwise-and

假设我有一个长度为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可以在没有强制执行的情况下恢复吗?

2 个答案:

答案 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] - 我们知道)。