两个明文字符串的异或解密

XOR decryption of two plaintext strings

我在我的 AP Java class 中被分配解密以下内容: umzDlBF8aFix

使用以下密钥: oE2dpffzEiFD

唯一的问题是我不知道如何进行异或来解密这些。我已经把它们变成二进制文件了:

键:101000|000100|110110|011101|101001|011111|110011|000100|100010|000101|000011

密文:110110|100110|110011|100101|000001|111100|011010|000101|100011|110001

但我不知道该怎么办。如果你能帮我解决这个问题,那就太好了!代码也很好,但不需要。

万分感谢!

XOR 运算符有 属性 T XOR K XOR K == T,所以如果你想用密钥 K 加密明文 T,你应用运算 C = T XOR K,并且为了解密文本,您只需再次应用相同的操作(T = C XOR K)。您可以使用 for 循环或函数式编程映射将 XOR 运算应用于明文中的每个字节。

编辑:如果您需要它,编程语言中的 XOR 运算符由字符“^”表示,因此 A ^ B 表示 A XOR B。

EDIT2:T XOR K XOR K == T 的简单证明,这样您就不必像魔术一样接受它:

  • K XOR K 显然等于 0
  • T XOR 0 显然等于 T
  • 由于异或运算符与二进制数结合,我们可以将T XOR K XOR K写成T XOR (K XOR K) == T XOR 0 == T

您不需要将它们转换为二进制文件。 XOR 是一种按位运算,因此您可以将两个字节异或在一起,就像将一个字节的每一位与另一个字节的相应位进行异或。

只需编写一个从零开始直到(不包括)密码长度的循环,其中您从密码中读取每个字符,将其与密钥中的相应字符进行异或,并将结果附加到 StringBuilder .然后在 StringBuilder 上调用 .toString() 以获得结果。

如果您的编译器抱怨它不能对字符进行异或,则将每个 char 转换为 byte,在字节之间执行异或,然后将结果转换为 char .

String class 有一个 charAt() 方法,它允许您从字符串中的特定索引获取字符。或者,您可以首先获取每个字符串的内容作为 char 数组。 (还有另一个功能。)

作为奖励,您可以使密钥的长度不必与密码的长度相同。您可以维护一个单独的索引来寻址密码的字符,当该索引达到密码的长度时,您可以将其设置回零,从而从头开始读取密码。

正如其他人所说,"xor" 是一种很棒的加密机制,因为加密和解密是完全相同的操作。如果您只使用密钥的每个部分一次,您将拥有最安全的加密算法。

如果您重复使用密钥的任何部分,它就会变成最糟糕的加密机制之一,因为这很容易破解。

你在这里遇到的问题是 - 你如何从字符到你想要加密的值。 您可以采用 Unicode 字符值,但您会得到带有密文和密钥的虚假结果。按原样使用 Unicode 的问题还在于,您可能会在 encryption/decryption 之后得到不可打印的字符,这通常不是问题,但在教科书示例中很难打印不可打印的字符。

为了解密你的文本,我假设字符的翻译是这样的。

  • A - Z => 0 - 25
  • a - z => 26 - 51
  • 0 - 9 => 52 - 61

(我不需要猜测 62/63 是多少,但 space 和点将是很好的猜测)。

使用这个假设和异或,我得到你的密文 umzDlBF8aFix 和你的密钥 oE2dpffzEiFD,最后得到明文 GiFeMeaPenny

因为这是可读的英文 - “给我一分钱” - 看起来上面的假设是合理的。