两个明文字符串的异或解密
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
。
因为这是可读的英文 - “给我一分钱” - 看起来上面的假设是合理的。
我在我的 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 - 25a
-z
=> 26 - 510
-9
=> 52 - 61
(我不需要猜测 62/63 是多少,但 space 和点将是很好的猜测)。
使用这个假设和异或,我得到你的密文 umzDlBF8aFix
和你的密钥 oE2dpffzEiFD
,最后得到明文 GiFeMeaPenny
。
因为这是可读的英文 - “给我一分钱” - 看起来上面的假设是合理的。