Python 3.6密码破解程序调用类方法报错:缺少pause参数
解决密码破解程序中“pause is required, not given”报错的问题
我来帮你分析下问题所在,以及如何修复:
错误原因
你遇到的报错核心问题是直接用类Cracking调用了实例方法ReturnPosPass。实例方法的第一个参数self需要接收类的实例对象,当你用Cracking.ReturnPosPass(30)调用时,Python会把30当成self参数,而原本需要的pause参数就没传入,所以才会提示“pause is required, not given”。
另外还有两个潜在问题需要解决:
ReturnPosPass里是无限循环,直接调用会阻塞主线程,导致破解线程无法正常运行。posPass是被破解线程和打印线程共享的变量,没有线程同步机制,可能会出现读取到不完整/不一致值的情况。
修复步骤
1. 用实例调用打印方法,并放到线程中执行
不要直接用类调用ReturnPosPass,而是用你已经创建好的bgCrack实例,并且把这个打印任务放到新线程里,避免阻塞主线程:
# 启动破解线程 bgCrack = Cracking(values, args.ActualPass, dataSet) bgCrack.start() # 启动定期打印的线程 print_thread = threading.Thread(target=bgCrack.ReturnPosPass, args=(30,)) print_thread.start()
2. 添加线程锁保证共享变量安全
在类的__init__方法里初始化一个线程锁,用来保护共享的posPass变量:
def __init__(self, values, ActualPass, dataSet): threading.Thread.__init__(self) self.passLen, self.cracked, self.values, self.ActualPass, self.dataSet = 1, False, values, ActualPass, dataSet self.lock = threading.Lock() # 添加线程锁 self.posPass = "" # 初始化posPass,避免首次打印时报错
然后在修改posPass和读取posPass的地方加锁:
- 修改
run方法里的posPass赋值:
with self.lock: self.posPass = "".join(value)
- 修改
ReturnPosPass方法的打印逻辑,同时添加循环终止条件(当密码破解完成时停止打印):
def ReturnPosPass(self, pause): while not self.cracked: time.sleep(pause) with self.lock: print(self.posPass)
完整修改后的代码
import threading import time import itertools import hashlib # 假设args是已定义的对象 class Cracking(threading.Thread): def __init__(self, values, ActualPass, dataSet): threading.Thread.__init__(self) self.passLen, self.cracked, self.values, self.ActualPass, self.dataSet = 1, False, values, ActualPass, dataSet self.lock = threading.Lock() self.posPass = "" def run(self): while self.cracked == False: startTime = time.time() for value in itertools.product(self.values, repeat=self.passLen): with self.lock: self.posPass = "".join(value) hashedPass = hashlib.sha512(self.posPass.encode()).hexdigest() if hashedPass == self.ActualPass: endTime = time.time() print("*" * 100) print("Password Cracked!") print(f"The password is '{self.posPass}'.") print(f"Password found using the '{self.dataSet}' data set. It took {(endTime - startTime) / 60} minutes.") self.cracked = True return self.passLen += 1 print(f"Password was not found using the '{self.dataSet}' data set.") def ReturnPosPass(self, pause): while not self.cracked: time.sleep(pause) with self.lock: print(self.posPass) # 假设以下变量已定义 values = ['a','b','c'] args = type('Args', (), {'ActualPass': 'xxx'})() dataSet = 'test' bgCrack = Cracking(values, args.ActualPass, dataSet) bgCrack.start() print_thread = threading.Thread(target=bgCrack.ReturnPosPass, args=(30,)) print_thread.start()
额外说明
- 我把
exit(0)换成了return,因为在线程里调用exit(0)会直接终止整个程序,而不是只结束当前线程,用return更安全,只会结束破解线程。 - 初始化了
self.posPass为空字符串,避免打印线程在破解线程第一次赋值前尝试打印导致的错误。
内容的提问来源于stack exchange,提问作者RiceyKrispie
相关产品推荐
相关产品推荐

