钥匙暴力

2024-09-21 09:33:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要找到一个密码钥匙。键的长度是10个个字符,并且键中字母的顺序是3,7,2,1,4,5,6,10,8,9。我也知道钥匙的md5。在

所以我写了

mystring = "abcdefghijklmnopqrstuvwxyz"
for letter3 in mystring:
    for letter7 in mystring[mystring.index(letter3):]:
        for letter2 in mystring[:mystring.index(letter7)]:
            for letter1 in mystring[:mystring.index(letter2)]:
                for letter4 in mystring[mystring.index(letter1):]:
                    for letter5 in mystring[mystring.index(letter4):]:
                        for letter6 in mystring[mystring.index(letter4):]:
                            for letter10 in mystring[mystring.index(leter6):]:  
                                for letter8 in mystring[:mystring.index(letter10)]:
                                    for letter9 in mystring[mystring.index(letter8):]:
                                        strr = "".join([letter1,letter2,letter3,letter4,letter5,letter6,letter7,letter8,letter9,letter10])
                                        if hashlib.md5(strr).hexdigest() == md5:
                                            print "key = " ,strr
                                            break

字符顺序:

关键是:

^{pr2}$

钥匙按字母顺序排列:

|letter3|letter7|letter2|letter1|letter4|letter5|letter6|letter10|letter8|letter9|

问题是时间(在外循环中一次迭代需要大约6小时)。有什么建议可以优化循环的范围吗?在


Tags: inforindexmd5钥匙mystringletter3letter1
2条回答

解决方案在底部


你很亲密。你想要的是。。。在

mystring = "abcdefghijklmnopqrstuvwxyz"
for letter1 in mystring:
    for letter2 in mystring[mystring.index(letter1):]:
        for letter3 in mystring[mystring.index(letter2):]:
            for letter4 in mystring[mystring.index(letter3):]:
                for letter5 in mystring[mystring.index(letter4):]:
                    for letter6 in mystring[mystring.index(letter5):]:
                        for letter7 in mystring[mystring.index(letter6):]:
                            for letter8 in mystring[mystring.index(leter7):]:  
                                for letter9 in mystring[mystring.index(letter8):]:
                                    for letter10 in mystring[mystring.index(letter9):]:
                                        strr = "".join([letter3,letter7,letter2,letter1,letter4,letter5,letter6,letter10,letter8,letter9])
                                        if hashlib.md5(strr).hexdigest() == md5:
                                            print "key = " ,strr
                                            break

这个循环严重减少了迭代次数,因为搜索的字符更少。它的外循环搜索的字符数少于它的每个循环。注意每个循环在同一个方向上搜索时,它是如何组织起来的。在

但它也是非常慢的,因为mystring.index()是一个缓慢的操作。我们可以通过不使用mystring.index()来加快速度。。。在

^{pr2}$

不过,这仍然是非常慢的,因为它有大量的迭代。在

这里的诀窍是itertools。。。在

mystring = "abcdefghijklmnopqrstuvwxyz"

import itertools

for L1, L2, L3, L4, L5, L6, L7, L8, L9, L10 in itertools.combinations_with_replacement(mystring, 10):
    strr = "".join([L3, L7, L2, L1, L4, L5, L6, L10, L8, L9])
    if hashlib.md5(strr).hexdigest() == 'a50e38475041f76219748ee22c4377d4':
        print ('key = {}'.format(strr))
        break

itertools.combinations_with_replacement()是在python中处理这类嵌套循环的方法,其中A>;=B>;=C>;=&ct,而且速度相当快。这是最快的解决办法。在

如果将其编译为机器代码,您会发现for循环包含四个部分。首先从内存加载当前迭代整数,然后从给定数组加载字母。然后执行for循环中的任何内容,最后递增索引,如果条件仍然成立,则执行条件跳转回到for循环的开头。在

优化这个过程的唯一方法(尽管我不能断言python;我尝试过优化C的for循环)是去掉增量部分,而使用常量。也就是说,手动布局字母的迭代。也就是说,去掉for循环,复制并粘贴数千行代码。这显然不太理想,也不可重用,我们开始优化的for循环已经不复存在了。在

我想我想说的是for循环已经非常优化了,它是组装中非常基本的东西。毕竟你是在用暴力来强迫它。在

相关问题 更多 >

    热门问题