我已经成功完成并通过了我正在进行的课程的项目,我创建了所有可能的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
答案 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("")