繁体   English   中英

Memory 在 python 中使用 unrar lib 检查字典密码时的使用情况积累

[英]Memory usage buildup while dictionary password checking using unrar lib in python

我在 python 中写了一些粗略的代码,用于检查字典文件中密码保护的 rar 存档的密码。 我什至添加了一些多线程,运行得很好。 不幸的是,随着脚本遍历密码列表,memory 的使用率开始增长。 通过超过 10k 次尝试,memory 的使用量超过 10GB...我在 unrar lib 文档中找不到任何释放资源的方法,使用 gc.collector 也没有帮助。 每次密码检查后如何释放缓冲区? 这是代码:

import os
import os.path
import fileinput
import sys
from unrar import rarfile
import gc
import threading
import linecache

class App():
    def check(fraction, n):
        FILE = sys.argv[1]
        DICT = sys.argv[2]
        
        with open(DICT, 'r') as passdict:
            k = len([0 for l in passdict])
        
        counter = int(k / n)
        start = counter * fraction
        stop = counter * (fraction + 1)
        i = start
        print('fr: %s start: %s stop: %s'% (fraction, start, stop))
        while i < stop:
            p = linecache.getline(DICT, i)
            #print(i)              
            try:
                rf = rarfile.RarFile(FILE, pwd=p)
                if len(rf.namelist())>0:
                    print(p)
                    
                    break
                
                i += 1
                pass
            except rarfile.BadRarFile:
                gc.collect(generation=0)
                
                i += 1
                pass
        return
        

if __name__ == '__main__':
    for k in range(6):
        t = threading.Thread(target=App.check, args=(k, 6,))
        t.start()

编辑-好的,所以我更改为 rarfile lib (pypi.org/project/rarfile),memory 没有累积,但多线程停止工作,而且它的工作速度也慢得多......看起来它都在一个上运行线程(任务管理器):/

我想我修好了。 不幸的是,尝试使用 never 库没有帮助。 好吧,它帮助解决了 memory 问题,但不知何故它不想进行多线程处理,所以它真的很慢。 我设法修复了 unrar 库 - 我在异常语句中添加了对 _close function 的调用。 看起来它只是在异常退出时没有释放资源——比如密码错误。 也许它对具有加密文件名的档案(如我的情况)这样做,但我没有检查。 这是 unrar 库的 rarfile.py 中的修改代码:

def _read_header(self, handle):
    """Read current member header into a RarInfo object."""
    header_data = unrarlib.RARHeaderDataEx()
    try:
        res = unrarlib.RARReadHeaderEx(handle, ctypes.byref(header_data))
        rarinfo = RarInfo(header=header_data)
    except unrarlib.ArchiveEnd:
        return None
    except unrarlib.MissingPassword:
        raise RuntimeError("Archive is encrypted, password required")
    except unrarlib.BadPassword:
        raise RuntimeError("Bad password for Archive")
    except unrarlib.UnrarException as e:
        self._close(handle) #This line fixes the memory issue
        raise BadRarFile(str(e))

    return rarinfo

这是我修改后的脚本:

import os
import os.path
import fileinput
import sys
import re
from unrar import rarfile
import threading
import linecache

class App():
    def check(fraction, n):
        FILE = sys.argv[1]
        DICT = sys.argv[2]
        
        with open(DICT, 'r') as passdict:
            k = len([0 for l in passdict])
        
        counter = int(k / n)
        start = counter * fraction
        stop = counter * (fraction + 1)
        i = start
        print('fr: %s start: %s stop: %s'% (fraction, start, stop))
        while i <= stop:
            p = re.search('\S*',linecache.getline(DICT, i)).group()
            try:
                with rarfile.RarFile(FILE, pwd=p) as rf:
                    rf.extractall(path='D:\\',pwd=p)
                    if len(rf.namelist())>0:
                        print(p)
                        break
                    i += 1
                pass
            except:
                i += 1
                pass
        print('stop')
        return
        

if __name__ == '__main__':
    for k in range(8):
        t = threading.Thread(target=App.check, args=(k, 8,))
        t.start()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM