降低python中字典暴力的复杂性

降低python中字典暴力的复杂性,python,dictionary,cryptography,complexity-theory,brute-force,Python,Dictionary,Cryptography,Complexity Theory,Brute Force,我有一个如下的程序,它基本上比较标准字典中所有可能单词的异或,并将异或结果与密文的异或结果进行比较,但我猜复杂度是O(n2)。我不知道如何降低复杂性 def find_collision(): a = int("4ADD55BA941FE954",16) ^ int("5AC643BE8504E35E",16) with open("/usr/share/dict/words", "r") as f: alist = [line.rstrip() for line

我有一个如下的程序,它基本上比较标准字典中所有可能单词的异或,并将异或结果与密文的异或结果进行比较,但我猜复杂度是O(n2)。我不知道如何降低复杂性

def find_collision():
    a = int("4ADD55BA941FE954",16) ^ int("5AC643BE8504E35E",16)
    with open("/usr/share/dict/words", "r") as f:
        alist = [line.rstrip() for line in f]
    b = len(alist)

    for i in range(0,b,1):
        for j in range(i,b,1):
        if(((int(alist[i].encode('hex'), 16))^ (int(alist[j].encode('hex'), 16)))==a):
            print("Plain Text1: "+alist[i]+'\n'+"Plain Text2: "+alist[j])
            #print "Yes"
            break

任何帮助都将不胜感激。

首先,让我们尽量简化

def find_collision():
    key = 0b1000000011011000101100000010000010001000110110000101000001010
    # that's 0x4ADD55BA941FE954^0x5AC643BE8504E35E
然后,我们方便的dandy
itertools
模块可以为大列表完成繁重的工作。这将取代嵌套的
for
循环,并且可能工作得更快

from itertools import combinations
##def find_collision()
##    key = 0b1000000011011000101100000010000010001000110110000101000001010
with open("/usr/share/dict/words", "r") as f:
    full_wordlist = combinations( map(str.rstrip,f.readlines()), 2 )
    # Combinations( { ('word1','word2'),('word1','word3'),('word1','word4'),
                    ('word2','word3') ... } )
但我们并不真正关心整件事,是吗?我们只关心碰撞,所以让我们来做碰撞,好吗编辑:由于这里肯定会有单词,我们不能使用十六进制,请执行以下操作:

#instead of full_wordlist = combinations(...)

import re
with open("usr/share/dict/words","r") as f:
    words = (word for word in map(str.rstrip,f.readlines()) if not re.search(r"[^0-9a-fA-F]",word))
    # you can avoid the need for regex by doing:
    # words = (word for word in map(str.rstrip,f.readlines()) if
    #         not any(char not in "0123456789abcdefABCDEF" for char in word))
    collisions = [keypair for keypair in combinations(words,2)
                 if bin(int(keypair[0],base=16)^int(keypair[1],base=16)) == key]
然后用一些理智的东西,比如:

for collision in collisions:
    print("Collision between {0[0]}^{0[1]} and key".format(collision))

如果您不需要知道哪些键发生碰撞,只要有任何键发生碰撞,您就可以将它们全部放入
集合
中,然后查看
集合
的长度是否与
列表
@adsmith的长度相同。我完全不明白您所说的:(我可以请您重新表述一下吗?我也不太明白您的代码试图做什么。它看起来需要
0x4ADD55BA941FE954^0x5AC643BE8504E35E
(即
0b10000000110101000101100000010001000110001101010000010
)并将其与
dict/words
XOR'd中的每两项进行比较,对吗?糟糕的是,上一个listcomp总是会返回一个
TypeError
,就像它试图执行
str^str
。我修复了它。但我得到了这个错误..回溯(最近的调用last):文件“”,第1行,在find\u collision()文件中,第7行,如果bin(int(keypair[0],base=16)^int(keypair[1],base=16))==key]ValueError:int()的文本无效,以16为基数:“A”听起来像词典中的一个词是
“A”
。由于明显的原因,这不起作用。您可能可以更早地制作一个从单词列表中提取的生成器。我会编辑…@user2888239我已经编辑过,这是一种方法。不过,可能有更好的方法。我会继续思考。