首页 > 解决方案 > 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

标签: python

解决方案


以下按预期工作(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.


推荐阅读