Python暴力密码猜测器

时间:2018-05-07 13:50:47

标签: python arrays string function recursion

我正在课堂上做一个关于密码猜测器的任务。我偶然发现了很多试图解决这个问题的问题,我的第一个方法是使用for循环(下面的代码),但我意识到循环的数量是多少。等于字符串的长度。

a_z = 'abcdefghijklmnopqrstuvwxyz'
pasw = 'dog'
tests = 0
guess = ''
azlen = len(a_z)

for i in range(azlen):
    for j in range(azlen):
        for k in range(azlen):
            guess = a_z[i] + a_z[j] + a_z[k]
            tests += 1
            if guess == pasw:
                print('Got "{}" after {} tests'.format(guess, str(tests)))
                break

input()

上述计划非常具体。仅当输入正好3个字符时才有效。我读到你可以使用一个名为intertools的包,但是,我真的想找到另一种方法。我想过使用递归但是不知道从哪里开始。

4 个答案:

答案 0 :(得分:1)

import string
import itertools

for possible_password in itertools.permutations(string.ascii_letters, 3): 
    print(possible_password)

答案 1 :(得分:0)

如果你不想使用itertools,你当然可以通过递归来做到这一点,递归可以使用任何(合理的)长度的密码 - 它没有连接到三个字符。基本上,每次递归调用都会尝试将字母表中的新字符附加到您的运行值guess。基本情况是当猜测获得与您正在寻找的值相同的长度时,在这种情况下,您检查匹配。如果找到匹配项,则返回您已成功的指示(我使用return True),以便您可以将任何进一步的搜索短路。否则,返回失败指示(return False)。使用global计数器会使它更加丑陋,但会产生您报告的相同结果。

ALPHABET = 'abcdefghijklmnopqrstuvwxyz'

def brute_force_guesser(passwd, guess = ''):
    global _bfg_counter
    if len(guess) == 0:
        _bfg_counter = 0
    if len(guess) == len(passwd):
        _bfg_counter += 1
        if guess == passwd:
            print('Got "{}" after {} tests'.format(guess, str(_bfg_counter)))
            return True
        return False
    else:
        for c in ALPHABET:
            if brute_force_guesser(passwd, guess + c):
                return True
        return False

brute_force_guesser('dog')    # => Got "dog" after 2399 tests
brute_force_guesser('doggy')  # => Got "doggy" after 1621229 tests

避免全局计数器的一种方法是使用多个返回值:

ALPHABET = 'abcdefghijklmnopqrstuvwxyz'

def brute_force_guesser(target, guess = '', counter = 0):
    if len(guess) == len(target):
        counter += 1
        if guess == target:
            print('Got "{}" after {} tests'.format(guess, str(counter)))
            return True, counter
        return False, counter
    else:
        for c in ALPHABET:
            target_found, counter = brute_force_guesser(target, guess + c, counter)
            if target_found:
                return True, counter
        return False, counter

brute_force_guesser('dog')    # => Got "dog" after 2399 tests
brute_force_guesser('doggy')  # => Got "doggy" after 1621229 tests

答案 2 :(得分:0)

这是我的完整答案,对不起,如果它不整洁,我仍然是编码的新手。归功于@JohnColeman使用基础的好主意。

equals

答案 3 :(得分:0)

import itertools
import string

def guess_password(real):
    chars = string.ascii_lowercase + string.digits
    attempts = 0
    for password_length in range(1, 20):
        for guess in itertools.product(chars, repeat=password_length):
            attempts += 1
            guess = ''.join(guess)
            if guess == real:
                return 'the password is {}, found in {} guesses.'.format(guess, attempts)
            print(guess, attempts)

print(guess_password('abc'))