Python多线程哈希破解求助:互斥实现及功能异常修复
哈希破解多线程脚本问题修复方案
核心问题分析与修复思路
针对你遇到的三个问题,逐一给出具体代码修正方案:
1. 线程重复执行相同任务(性能无提升)
问题根源:所有线程共享同一字典数据源,无任务分发机制,导致每个线程都遍历完整字典内容。
修复方案:用queue.Queue实现线程安全的任务队列,将待破解密码条目预先放入队列,每个线程从队列取唯一任务,取完即止。
2. 安全暂停功能失效
问题根源:普通全局变量作为暂停标志不具备线程可见性,线程无法及时感知状态变化。
修复方案:用threading.Event作为线程安全的暂停/终止信号,线程循环中定期检查该信号状态。
3. 打印异常与冗余换行
问题根源:多线程同时调用print时,输出流被抢占导致内容混乱、换行冗余。
修复方案:用threading.Lock实现打印操作的互斥,确保同一时间只有一个线程能输出内容。
修复后的完整代码示例
import hashlib import threading import queue import time # 全局配置 TARGET_HASH = "5f4dcc3b5aa765d61d8327deb882cf99" # 示例哈希值(对应密码"password") DICTIONARY_PATH = "passwords.txt" PAUSE_EVENT = threading.Event() PRINT_LOCK = threading.Lock() TASK_QUEUE = queue.Queue() def hash_crack_worker(): while not TASK_QUEUE.empty(): # 检查暂停信号 while PAUSE_EVENT.is_set(): time.sleep(0.1) try: password = TASK_QUEUE.get(block=False) # 计算哈希值 hashed_password = hashlib.md5(password.encode()).hexdigest() if hashed_password == TARGET_HASH: with PRINT_LOCK: print(f"[SUCCESS] 找到密码: {password}") # 找到密码后终止所有线程 PAUSE_EVENT.set() break # 可选:打印进度(需加锁) # with PRINT_LOCK: # print(f"[尝试] {password}") except queue.Empty: break except Exception as e: with PRINT_LOCK: print(f"[错误] 线程执行异常: {str(e)}") finally: TASK_QUEUE.task_done() def load_dictionary(): """加载字典文件到任务队列""" with open(DICTIONARY_PATH, "r", encoding="utf-8") as f: for line in f: password = line.strip() if password: TASK_QUEUE.put(password) def main(): # 加载字典到队列 load_dictionary() if TASK_QUEUE.empty(): print("字典文件为空或路径错误") return # 创建线程 thread_count = 4 # 根据CPU核心数调整 threads = [] for _ in range(thread_count): t = threading.Thread(target=hash_crack_worker) t.daemon = True threads.append(t) t.start() # 安全暂停/终止控制 try: while True: cmd = input("输入 'pause' 暂停,'resume' 恢复,'quit' 退出: ").strip().lower() if cmd == "pause": PAUSE_EVENT.set() print("已暂停破解") elif cmd == "resume": PAUSE_EVENT.clear() print("已恢复破解") elif cmd == "quit": PAUSE_EVENT.set() break else: print("无效命令") except KeyboardInterrupt: PAUSE_EVENT.set() # 等待所有线程完成 TASK_QUEUE.join() print("破解任务结束") if __name__ == "__main__": main()
关键修改点说明
- 任务队列:
queue.Queue自动处理线程间任务分发,确保每个密码只被一个线程处理,避免重复计算。 - 暂停信号:
threading.Event是线程安全的状态标志,线程通过is_set()检查是否需要暂停,clear()恢复运行。 - 打印互斥:
PRINT_LOCK确保print操作原子性,避免多线程输出混乱。 - 守护线程:设置
daemon=True,主线程退出时子线程自动终止,避免残留线程。
内容的提问来源于stack exchange,提问作者Don Schulz
相关产品推荐
相关产品推荐

