我在家里的旧电脑上发现了一个加密的zip存档。很久之后我忘记了密码。依稀记得密码是6个字母加数字。我从网上下载了很多破解密码。可用的软件都没有任何效果,所以我想到用Python编写一个用于暴力破解密码的脚本。Python有内置模块zipfile可以做这个,测试一波,测试文件,设置解压密码为123importzipfile#创建文件句柄file=zipfile.ZipFile("Test.zip",'r')#提取压缩文件中的内容,注意密码必须是bytes格式,path表示提取到哪里file.extractall(path='.',pwd='123'.encode('utf-8'))运行效果如下图所示,提取成功。好了,我开始破解旧文件的密码了。为了提高速度,我加入了多线程初始代码:-8'))defresult(f):exception=f.exception()ifnotexception:#如果没有得到异常,则破解成功print('密码为:',f.pwd)globalflagflag=Falseif__name__=='__main__':#创建flag判断密码是否破解成功flag=True#创建线程池pool=ThreadPoolExecutor(100)nums=[str(i)foriinrange(10)]chrs=[chr(i)foriinrange(65,91)]#生成数字+字母的6位密码password_lst=itertools.permutations(nums+chrs,6)#创建文件句柄zfile=zipfile.ZipFile("encryptedfile.zip",'r')forpwdinpassword_lst:ifnotflag:breakf=pool.submit(extract,zfile,pwd)f.pwd=pwdf.pool=poolf.add_done_callback(result)这段代码有问题,运行一会内存就爆了!原因:ThreadPoolExecutor默认使用unboundedQueue,试密码的速度赶不上生产密码的速度,生产任务会无限添加到队列中。导致内存满。内存直接飙到95:然后程序崩溃了:看源码发现ThreadPoolExecutor内部使用了无界队列,所以内存直接满了,重写ThreadPoolExecutor类中的_work_queue属性,把无界队列改成有界队列。这样就不会出现内存满的问题了,看代码:importqueuefromconcurrent.futuresimportThreadPoolExecutorclassBoundedThreadPoolExecutor(ThreadPoolExecutor):def__init__(self,max_workers=None,thread_name_prefix=''):super().__init__(max_workers,thread_name_prefix)self。_work_queue=queueQueue(self._max_workers*2)#设置队列大小,最终破解成功,如下图。
