在递归调用中返回麻烦

时间:2017-07-25 04:44:52

标签: python recursion

我已经成功完成并通过了我正在进行的课程的项目,我创建了所有可能的4个字母密码组合来破解DES哈希。当我找到一个匹配时,它应该立即返回,但我知道我的功能设计很差。我理解基本的递归,但我总是无法理解它的任何有用的目的。在这种情况下,我发现我可以使方法返回的唯一方法是检查封装函数中初始化的密码变量以及非本地属性。

在我找到最终解决方案之前,我没有非本地工作,但是如果发现密码正确打印出密码,它会持续一段时间而不返回任何内容。

如何通过正确传播值来正确使用递归来返回正确的密码?感谢您提供的任何帮助或提示!

def brute_force_crack(hashed_pass):
    char_list = create_possible_chars()

    # Store all string combinations
    password = ""

    # Build the combos adding each letter to each prefix and then to combos.
    def build_combos(curr_str):

        nonlocal password

        # Check password to return early
        if password != "":
            return
        if len(curr_str) == 4:
            return

        for letter in char_list:
            # Add letter to curr_str to build up the combo
            curr_str += letter

            if is_password(curr_str, hashed_pass):
                password = curr_str
                break

            build_combos(curr_str)
            # Reset curr_str to be used again in this iteration without the added letter
            curr_str = curr_str[:-1]

    build_combos("")
    return password

2 个答案:

答案 0 :(得分:1)

只要确保找到正确答案,就可以退货。通过您的函数的每条路径都应该返回一些东西,无论是正确的密码还是指示失败的标记值(例如None)。看看下面的内容是否合理:

import string

def create_possible_chars():
    return string.ascii_lowercase

# Dummy implementation, check for the password reversed
def is_password(curr_str, hashed_pass):
    return ''.join(reversed(curr_str)) == hashed_pass

def brute_force_crack(hashed_pass):
    char_list = create_possible_chars()

    def build_combos(curr_str=""):
        # Base case: already at four characters, give up
        if len(curr_str) == 4:
            return None

        for letter in char_list:
            # Try adding this letter
            guess = curr_str + letter

            if is_password(guess, hashed_pass):
                # If this is the password, return it
                return guess
            else:
                # Recurse
                result = build_combos(guess)

                # If we found the password, return it
                if result is not None:
                    return result

        # We failed to find the psasword
        return None

    return build_combos()

print(brute_force_crack("beef"))  # feeb

答案 1 :(得分:1)

您应该在找到时让递归函数返回正确的密码,而不是设置非局部变量。

其次,在递归函数开始时执行密码检查,同时检查是否有失败。这可能在第一次看起来有些过分(因为空字符串不匹配),但它是更干净的代码。

以下是它的外观:

def brute_force_crack(hashed_pass):
    char_list = create_possible_chars()

    # Build the combos adding each letter to each prefix and then to combos.
    def build_combos(curr_str):
        # Check for success
        if is_password(curr_str, hashed_pass):
            # Return the match
            return curr_str
        # Check for failure
        if len(curr_str) >= 4:
            return

        for letter in char_list:
            # Add letter via argument to build up the combo
            password = build_combos(curr_str + letter)
            # If a result is returned, we can quit
            if password:
                return password

    # Return whatever is returned recursively
    return build_combos("")