Python如何在条件满足时跳出内层for循环?MD5暴力破解脚本问题求助
问题原因分析
- 核心错误是使用了
itertools.combinations生成候选密码:该函数生成的是不重复、元素顺序严格与输入字符集顺序一致的组合。你的字符集顺序是先小写字母、再大写字母、再符号和数字,所以永远无法生成类似AbCdE这类大小写交替的字符串,除单字符Z外,其余多字符明文都不符合combinations的生成规则,自然无法匹配。 - 现有
break仅能跳出最内层遍历候选组合的循环,无法跳出上层的长度遍历循环,匹配成功后仍会继续枚举更长的字符串,属于无效执行。 range(len(abc_list))从0开始遍历,会先生成无意义的空字符串,浪费算力。- 把迭代器转成
list会一次性加载所有候选组合到内存,长密码场景下会占用极高内存,甚至导致程序崩溃。
修复后的代码
import hashlib import itertools # 字符集保持不变 abc = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@0123456789" def combo(): with open("hashes.txt", "r", encoding="utf-8") as f: # 逐行读取待破解哈希,提前去重避免重复计算 target_hashes = [line.strip() for line in f if line.strip()] for target_hash in target_hashes: found = False # 从长度1开始枚举,最多枚举到你需要的最大长度即可,这里示例设到10位,可自行调整 for length in range(1, 11): # 用product生成所有指定长度的字符组合,允许重复、顺序任意 for candidate_tuple in itertools.product(abc, repeat=length): candidate = "".join(candidate_tuple) current_md5 = hashlib.md5(candidate.encode()).hexdigest() if current_md5 == target_hash: print(f"匹配成功:明文为 '{candidate}',哈希值为 {current_md5}") found = True break # 找到后跳出长度遍历循环 if found: break if __name__ == "__main__": combo()
改动说明
- 替换
itertools.combinations为itertools.product:可以生成所有指定长度的字符排列,允许重复字符、任意顺序,完全符合暴力枚举的需求,你需要的AD、God、AbCdE等明文都可以正常生成。 - 新增
found标志位:匹配到明文后,先跳出候选组合的内层循环,再通过标志位跳出长度遍历的中层循环,直接处理下一个待破解哈希,避免无效计算。 - 调整长度遍历范围:从1开始,设置合理的最大长度阈值(示例为10位),不需要遍历到整个字符集的长度,大幅减少无效计算。
- 用
with语句管理文件读取:自动关闭文件句柄,避免资源泄露。 - 去掉迭代器转
list的操作:直接迭代itertools.product返回的迭代器,按需生成候选组合,内存占用极低。
内容的提问来源于stack exchange,提问作者Obito
相关产品推荐
相关产品推荐

