首页 > 解决方案 > 在自身内部嵌套一个函数(我很绝望)

问题描述

精神疲惫。

仅针对上下文的解释,实际上不需要哈希帮助:

我正在尝试制作一个可以暴力破解散列字符串或密码的python脚本(仅供学习,我敢肯定那里有一些拉幅代码)。目标是创建一个函数,可以尝试不同字母的所有可能组合,从一个字符(a,b...y,z)开始,然后再尝试一个字符(aa,ab...zy,zz然后 aaa, aab... zzy, zzz) 不确定地直到找到匹配项。

首先,它要求您输入一个字符串(例如 aaaa),然后对字符串进行散列处理,然后尝试使用该函数强制该散列,最后该函数在找到匹配项时再次返回该字符串。

PASSWORD_INPUT = input("Password string input: ")
PASSWORD_HASH = encrypt_password(PASSWORD_INPUT)  # This returns the clean hash
found_password = old_decrypt()  # This is the function below
print(found_password)

我设法完成了这段丑陋的代码:

built_password = ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']

def old_decrypt():
    global built_password

    # First letter
    for a in range(len(characters)):  # Characters is a list with the abecedary
        built_password[0] = characters[a]
        if test_password(pretty(built_password)):  # This returns True if it matches
            return pretty(built_password)

        # Second letter
        for b in range(len(characters)):
            built_password[1] = characters[b]
            if test_password(pretty(built_password)):
                return pretty(built_password)

            # Third letter
            for c in range(len(characters)):
                built_password[2] = characters[c]
                if test_password(pretty(built_password)):
                    return pretty(built_password)

                # Fourth letter
                for d in range(len(characters)):
                    built_password[3] = characters[d]
                    if test_password(pretty(built_password)):
                        return pretty(built_password)

这样做的问题是它只适用于 4 个字母的字符串。

正如你所看到的,每个字母的循环几乎完全相同,所以我想“嘿,我可以把它变成一个单一的功能”......在痴迷地尝试了我脑海中浮现的一切 3 天后,我想到了这个:

# THIS WORKS
def decrypt(letters_amount_int):
    global built_password

    for function_num in range(letters_amount_int):
        for letter in range(len(characters)):

            built_password[function_num] = characters[letter]
            if letters_amount_int >= 1:
                decrypt(letters_amount_int - 1)

            if test_password(pretty(built_password)):
                return pretty(built_password)

# START
n = 1
while True:
    returned = decrypt(n)

# If it returns a string it gets printed, else trying to print None raises TypeError
    try:
        print("Found hash for: " + returned)
        break
    except TypeError:
        n += 1

函数得到一个“1”,尝试使用 1 个字母,如果它没有返回任何内容,它会得到一个“2”,然后尝试使用 2。它可以工作,但由于某种原因,它会产生大量不必要的循环,并以指数方式越来越多时间,我一直在打我的头,得出的结论是我不了解python的内部功能。

有人可以对此有所了解吗?谢谢

如果需要,这些是其他功能:

def encrypt_password(password_str):
    return hashlib.sha256(password_str.encode()).hexdigest()

def test_password(password_to_test_str):
    global PASSWORD_HASH
    if PASSWORD_HASH == encrypt_password(password_to_test_str):
        return True

characters = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
              'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
              'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
              'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D',
              'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
              'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
              'Y', 'Z']

标签: pythonfunctionfor-loopnestednested-loops

解决方案


在这种情况下,递归提供了一个非常优雅的解决方案:

def add_char(s, limit):
    if len(s) == limit:
        yield s
    else:
        for c in characters:
            yield from add_char(s + c, limit)


def generate_all_passwords_up_to_length(maxlen):
    for i in range(1, maxlen + 1):
        yield from add_char("", i)


for password in generate_all_passwords_up_to_length(5):
    test_password(password)

推荐阅读