如何使用暴力破解密码的所有排列?

Mil*_*Tom 9 python permutation brute-force python-3.x

所以我试图制作一个暴力破解密码的程序.

首先,我为长度为1的密码制作了一个程序:

password = input('What is your password?\n')
chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'

def brute_force():
    for char in chars:
        if char == password:
            return char

print(brute_force())
Run Code Online (Sandbox Code Playgroud)

然后我编辑了一个长度为2的密码:

def brute_force():
    guess = [None, None]
    for char in chars:
        guess[0] = char
        for char2 in chars:
            guess[1] = char2
            if ''.join(guess) == password:
                return ''.join(guess)
Run Code Online (Sandbox Code Playgroud)

最后我为长度为3的密码做了同样的事情:

def brute_force():
    guess = [None, None, None]
    for char in chars:
        guess[0] = char
        for char2 in chars:
            guess[1] = char2
            for char3 in chars:
                guess[2] = char3
                if ''.join(guess) == password:
                    return ''.join(guess)
Run Code Online (Sandbox Code Playgroud)

我怎么能概括为一个名为length的变量,它包含密码长度的整数值?

Joe*_*don 10

您可以使用以下递归函数:

def brute_force(string, length, goal):
    if not length:
        if string == goal:
            return string
        return False
    for c in chars:
         s = brute_force(string + c, length - 1, goal)
         if s:
             return s
    return False
Run Code Online (Sandbox Code Playgroud)

您可以使用以下语法调用:

>>> brute_force('', 3, 'bob')
'bob'
>>> brute_force('', 2, 'yo')
'yo'
Run Code Online (Sandbox Code Playgroud)

为什么这样做?

我们总是相互调用函数与三个变量:string,lengthgoal.变量string保持当前猜测到这一点,所以在第一例中,string将所有物质直至bobab,bo

下一个变量length包含要经过多少个字符,直到它string是正确的长度.

下一个变量goal是我们刚刚通过并与之进行比较的正确密码.

在功能的主体,我们需要先检查其中的情况length0(通过检查所做not length0计算结果为False).当我们已经有一个字符串是目标的长度并且我们只想检查它是否正确时就是这种情况.

如果匹配,那么我们返回字符串,否则我们返回False.我们返回解决方案或False指示调用我们的函数(堆栈中的上述调用),我们找到了正确的密码(或不是).

我们现在已经完成了案件,length = 0现在需要处理其他案件.

在这些情况下,目标是获取我们被调用的字符串并循环遍历所有字符chars,每次调用brute_force函数(递归)时,调用我们调用的字符串和该字符的串联结果(c).

这将创建一个类似于树的树,其中检查到原始的每个字符串length.

我们还需要知道在调用下一个函数时如何处理lengthgoal变量.

那么,要处理这些问题,我们只需要考虑下一个功能需要知道的内容.它已经有了string(因为这是连接字符串中下一个字符的结果chars)而且length只是少了一个,因为我们只是string通过连接添加一个并且goal显然将是相同的 - 我们是仍在搜索相同的密码.

现在我们已经调用了这个函数,它会在每个后续调用中从长度中减去一个函数,直到最终达到这种情况为止length == 0.我们再次处于简单的情况,并且已经知道该怎么做了!

因此,调用它后,该函数会返回一个两两件事,要么False表明最后一个节点没有找到密码(那么,这样的事情会发生的情况下ab达到我们的搜索月底bob就回来False之后没有解决办法是发现),或者,呼叫可以返回实际的解决方案.

处理这些情况很简单,如果我们得到了实际的解决方案,我们只想将其返回到链中,如果我们得到了fail(False),我们只想返回False并且这将向我们上方的节点表明我们没有成功并告诉它继续搜索.

所以现在,我们只需要知道如何调用该函数.我们只需要发送一个空的string,一个目标lengthgoal值,然后进行递归.


注意最后一件事是,如果你想让它更整洁,你可以修改函数定义:

def brute_force(length, goal, string=''):
    ...
Run Code Online (Sandbox Code Playgroud)

并在其中更改递归调用.这样,您可以使用以下内容调用该函数:brute_force(3, 'bob')并且不需要指定string应该从哪个开始.如果您愿意,这只是您可以添加的内容,但功能无需工作.


Thi*_*ien 10

除了向您展示如何工作的答案之外,我还想提请注意这样一个事实:标准库只有这个的功能,形状为itertools.product- itertools.permutations不是因为它不允许重复,因此只会生成猜测所有独特的字符:

from itertools import product

def brute_force():
    for length in range(min_length, max_length + 1):
        for p in product(chars, repeat=length):
            guess = ''.join(p)
            if guess == password:
                return guess
Run Code Online (Sandbox Code Playgroud)

  • 你需要`itertools.product`; 排列不包括重复字符. (2认同)