【问题标题】:How to build a reverse bitwise operation如何构建反向按位运算
【发布时间】:2020-02-09 23:24:01
【问题描述】:

按位逆运算

我有一组加密字节,我可以使用以下函数对其进行解密:

        byte b = (byte) (encrypted & 0xFF);
        return b >> 5 & 0x7 | (b & 0x1F) << 3;
    }
      
    0x51 >> 5 & 0x7 | 0x51 & 0x1F << 3 = 0x98
    ^                 ^

乍一看,它先于一个复杂的操作,所以我决定把它分成几部分。

我需要进行反向操作。我知道字节操作是如何工作的;位移似乎很容易逆转,但 AND 并不难。许多人在之前的帖子中认为您不能但想知道您对此的看法。

我注意到操作(b &amp; 0x1F) 只返回0x00x1F 的数字,当它到达0x20 时在0x0 处重新启动,所以连续直到0x39 返回0x20 和@987654329 @ 自然返回0x0

考虑一个可能的解决方案,我必须知道一个函数"x &amp; y = z"我知道“y”和“z”,例如"x + 0x1F = 0x1A"可以确定原始字节可能是下一个{0x1A, 0x3A, 0x5A, 0x7A, 0x9A, 0xBA, 0xDA, 0xFA}中的任何一个,但现在的问题是如何选择正确的。

尝试回答这个问题0xA1 &amp; 0x1F = 0x1,假设"x &amp; y = z",我们只知道y"z",可能的x只有{0x1, 0x21, 0x41, 0x61, 0x81, 0xA1, 0xC1, 0xE1},你可以看到答案在8个可能之间字节。

也许我提出的问题很糟糕,但我无法构建反向操作。您能给我您的意见或解释如何组合这种类型的操作吗?

【问题讨论】:

  • 总体来说是旋转,这样看很容易反转
  • 如果你做 1110 和 0100 你不能从结果 0100 反转,如果原来是 1110 或 0100 或 0101,那是不可能的。这不是一个双唯一的投影。

标签: java c# c++


【解决方案1】:

要找到反向操作,您应该尝试查看代码在整体上所做的操作,而不是单个操作。

| 的左操作数表示,

b 向右移动 5 位 &gt;&gt; 5 然后清除除最低有效三位 &amp; 0x7 之外的所有位。请注意,7 是二进制的 111。

上面得到b的最高3位并将它们一直向右移动。 1010 1100 将变为 0000 0101。

| 的右操作数表示,

清除除b 的最低5 位之外的所有位,然后将b 向左移动3 位。注意1F是二进制的0001 1111。

这将获取b 的最低有效 5 位,然后一直向左移动。 1010 1100 会变成 0110 0000。

最后,| 将两个结果组合在一起。

所以在高级抽象上,这段代码只是在一个字节中切换前 3 位和后 5 位。 1110 0000 将变为 0000 0111。

要反转这一点,只需切换前 5 位和后 3 位。

byte b = (byte) (decrypted & 0xFF);
return b >> 3 & 0x1F | (b & 0x7) << 5;

如果您觉得这个答案令人困惑,您可能想了解Bit Masks

【讨论】:

  • &amp; 0x1F&amp; 0x7 是多余的,它们用于将位归零,但在这种情况下,移位应该拉动0s,所以这只会使它更复杂。跨度>
  • @Dimfred IIRC Java 进行算术移位,而不是逻辑移位,因此不一定是 0。
  • 啊,好吧,应该在我的评论中添加 C++。但很高兴知道 Java 中的工作方式完全不同。
【解决方案2】:

只计算 256 字节的数组:m_encrypt;字节 -> 加密字节

如果是一对一的,那么它是可逆的,否则它不是。

计算解密数组m_decrypt via

for(int i=0; i< 256; i++)
  m_decrypt[m_encrypt[i]] = i;

【讨论】:

  • 自然,通过这种方式我们可以很容易地获得所有可能的字节,但这会产生8种可能性,例如对于0x1A字节,有3种8种可能的组合使用0x1F操作会产生0x1A作为响应: { 0x1A, 0x3A, 0x5A, 0x7A, 0x9A, 0xBA, 0xDA, 0xFA } 例如,如果我这样做 0x9A &amp; 0x1F = 0x1A 如果我只知道“y”和“z”,那么问题是否就像x &amp; y = z 选择正确的一样?也许我对问题的关注度很差,我需要从另一个角度看待它。也许我必须看到完整函数的结果才能推导出一些数学运算。
猜你喜欢
  • 2014-12-30
  • 2018-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多