python - Python:为什么这些看起来相同的字符串被评估为不相同
问题描述
我正在做一个有趣的密码分析练习。在练习中,我得到一个充满密文的 txt 文件,其中一个密文通过 xor'ing 与单个字符进行加密。我做了一些python来解决这个问题:
import enchant
d = enchant.Dict("en_US")
def decrypt(c):
l = len(c)
for i in range(100):
tmpKey = [i] * l
res = xor(tmpKey , c)
Sprime = str(bytes(res))[2:][:-1]
try:
B = False
split = Sprime.split()
for s in split:
if (d.check(s)):
B = True
else:
B = False
break
if B:
print(Sprime)
except:
continue
def xor(b1, b2):
b = bytearray(len(b1))
for i in range(len(b1)):
b[i] = b1[i] ^ b2[i]
return b
ccfile = open("4.txt", "r")
for aline in ccfile:
decrypt(bytearray.fromhex(aline))
ccfile.close()
这会产生一长串解密的明文。这是输出的摘录:
...
B 95ME\x03\x05\x15:\x02>\x00E\x17X\x1a\x1d\x00\xae2-B' \x1a]\x02H
n \xd93\x10.X\xff\xd7\x19|/?;)vp^3? a|\x19m2\x01\xd1#|
Now that the party is jumping\n
L \xaf\rqP\x08\x14UG\xe3\\\x15sC]t_\xa8\x13M~Mm\xae{\\BJ\x11
4 GN\r*@\xf1\x17\xe6\xe2\n*\x1f*\xf3\x00\xfa:\x1ebQ\rN\x07C$\xfe#\x06
3 04;&\x0eN\x17T3\x04(\x11JA\x03\xf4[)[SV\x1d2\x06\x0fL9?
...
在这里我们看到了明文"Now that the party is jumping\n"
。这是伟大的。
我的问题是我希望我的代码不仅能解密并向我显示所有文本,还能找到有效的明文。
在您可以看到的代码中,我尝试添加一些应该捕获有问题的纯文本的内容。无论出于何种原因,这一直不起作用!
我有这个小玩具示例,我尝试区分我要查找的明文:
d = enchant.Dict("en_US")
B = False
split = "Now that the party is jumping\n".split()
print(split)
for s in split:
if (d.check(s)):
B = True
else:
B = False
break
# If B is true, then the plaintext is valid english
这在我对字符串进行硬编码时有效。但是,一旦我实施“在行动”,它就不起作用了。然后我还注意到,当我比较两个字符串时,一个是硬编码的,另一个是在运行程序时简单输出的:
if (Sprime == "Now that the party is jumping\n"):
print("should be true at some point")
那么这个语句永远不会被触发。“现在派对正在跳跃\n”与“现在派对正在跳跃\n”不同。什么?为什么是这样?
编辑
原始问题可以[在这里找到][1]。
我现在已经测试了更多,并按字符比较了两个字符串。我现在有这个代码可以玩:
from os import stat
import enchant
d = enchant.Dict("en_US")
def decrypt(c):
l = len(c)
for i in range(100):
tmpKey = [i] * l
res = xor(tmpKey , c)
Sprime = str(bytes(res))[2:][:-1]
state = False
if (Sprime.startswith("Now")): #== "Now that the party is jumping\n"):
state = True
print(Sprime)
for s1,s2 in zip(Sprime, "Now that the party is jumping\n" +
""):
bb = s1 == s2
print(s1 + " ^ " + s2 + " = " + str(bb))
try:
if state:
print(Sprime)
B = False
split = Sprime.split()
for s in split:
if (d.check(s)):
B = True
else:
B = False
break
if B:
print(Sprime)
except:
continue
def xor(b1, b2):
b = bytearray(len(b1))
for i in range(len(b1)):
b[i] = b1[i] ^ b2[i]
return b
ccfile = open("4.txt", "r")
for aline in ccfile:
decrypt(bytearray.fromhex(aline))
ccfile.close()
当我的硬编码字符串以“\n”结尾时,比较会给我以下输出:
Now that the party is jumping\n
N ^ N = True
o ^ o = True
w ^ w = True
^ = True
t ^ t = True
h ^ h = True
a ^ a = True
t ^ t = True
^ = True
t ^ t = True
h ^ h = True
e ^ e = True
^ = True
p ^ p = True
a ^ a = True
r ^ r = True
t ^ t = True
y ^ y = True
^ = True
i ^ i = True
s ^ s = True
^ = True
j ^ j = True
u ^ u = True
m ^ m = True
p ^ p = True
i ^ i = True
n ^ n = True
g ^ g = True
\ ^ = False
所以它们不一样,因为传入的字符串末尾有 a \
,而硬编码的字符串将 解释\n
为实际的断线,而不是字符串。很好,所以我尝试将我的硬编码字符串更改为“现在派对正在跳跃”。但是,当我尝试测试这两个字符串是否相等时,它们仍然不匹配。世界上到底发生了什么?[1]:https ://cryptopals.com/sets/1/challenges/4
解决方案
以下按预期工作(Fedora 34,python3-3.9.5-2.fc34.x86_64):
import enchant
d = enchant.Dict("en_US")
phrase = input("Enter a phrase: ")
split = phrase.split()
print(split)
B = True
for s in split:
B = B and d.check(s)
print(B)
请注意,您可以将结果d.check(s)
分配给您的 boolean B
,无需使用if
来确定要分配的值。这里我只是累积结果。如果是较长的文本,您可能希望在找到False
.
推荐阅读
- java - Android:无法以编程方式将收件人设置为彩信意图
- arrays - 连接两个公式中的值的最正确方法,其中第一个公式中的每一行需要连接第二个公式中的所有值,依此类推
- python - openCV undistortPoints 矩阵操作数是一个空矩阵
- c++ - 用户流中的“覆盖”非虚拟运算符 << (...)
- stm32 - 使用显示总线接口将 TFT 屏幕与 STM32F446 连接
- python - Bytes 对象到数据框的列表
- android - 在 Android 项目上找不到证书路径的信任锚
- python - DRF Serializer 如何序列化我的数据并显示
- javascript - 更改后的反应状态未呈现
- python - Azure servicebus python - 如何发送一堆消息