欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

用python批量解压带密码的压缩包

程序员文章站 2022-04-15 17:32:38
项目地址:https://github.com/mario-hero/toolunrar环境需求 windows系统 python 3 对于解压rar文件,需要安装winrar...

项目地址:

https://github.com/mario-hero/toolunrar

环境需求

  • windows系统
  • python 3
  • 对于解压rar文件,需要安装winrar
  • 对于解压7z/zip等其他7-zip支持解压的文件,需要安装7-zip

用法 usage

直接拖入文件夹或压缩文件即可批量解压缩包含密码的压缩文件。如果拖入的是文件夹,则会把该文件夹下的压缩文件解压缩,但不进入下一级目录。通过设置passwd来设置字典,通过设置deleteit来设置解压后是否删除被成功解压的压缩文件。本脚本会通过文件的后缀识别该文件是否为压缩文件。

你可以把winrar目录下的unrar.exe和7-zip目录下的7z.exe直接复制到这个toolunrar.py文件的相同目录下,这样就可以携带使用了。

参数 parameters

  • passwd = ["hello","123456"] :你的密码本,该脚本会从这个数组中不断试验密码来解压缩,直到成功为止。
  • deleteit :一个危险的参数。为真时,该脚本会直接删除成功解压的压缩文件。为假则不会删除。
  • loc_winrar = "c:\program files\winrar\" 你的winrar安装位置。就算这个变量的设置的不对,该程序也会在可能的位置来寻找对应的程序。
  • loc_7z:7-zip的安装位置。
  • save_mode = true:如果该脚本无法通过后缀判断这是不是压缩文件,则不对该文件进行操作。

完整代码

#!/usr/bin/python3
# -*- coding: utf-8 -*-

# created by mario chen, 04.04.2021, shenzhen
# my github site: https://github.com/mario-hero

import sys
import os
import subprocess

# you can change it >>>>>

passwd     = ["123456","hello"]  # the possible passwords
deleteit   = false                                     # danger!! if it is true,will delete rar file after extraction
loc_winrar = "c:\\program files\\winrar\\"              # location of winrar
loc_7z     = "c:\\program files\\7-zip\\"               # location of 7-zip
save_mode  = true                                       # if the suffix of file doesn't look like a compressed file, then do nothing with it.

# <<<<< you can change it


program_rar  = "unrar.exe" # the program we use
program_7z   = "7z.exe"    # the program we use
loc_s_winrar = ["c:\\program files\\winrar\\","c:\\program files (x86)\\winrar\\","./",""] # some possible locations of winrar
loc_s_7z     = ["c:\\program files\\7-zip\\","c:\\program files (x86)\\7-zip\\","./",""]   # some possible locations of 7-zip
rar_file     = ["rar","zip","7z","tar","gz","xz","bzip2","gzip","wim","arj","cab","chm","cpio","cramfs","deb","dmg","fat","hfs","iso","lzh","lzma","mbr","msi","nsis","ntfs","rpm","squashfs","udf","vhd","xar","z"]
not_rar_file = ["jpg","exe","png","mkv","mp4","mp3","avi","mov","jpeg","wav","gif","mpeg","webp","txt","doc","docx","ppt","pptx","xls","xlsx","html","wps","torrent","swf","bmp","crdownload","xltd","downloading"]
enable_rar = false         # initial state only
enable_7z = false          # initial state only

# for guessing >>>
guess_flag_init     = ["密码", "码", "password", "password"]    #0
guess_flag_start_1  = [":", ":"]                            #1
guess_flag_start_2  = ["是", "为", "is", "are"," "]          #1
guess_flag_end      = ["\n","   "]                           #2
guess_flag_divide   = ["或是", "或", " or "]                 #3
# <<< for guessing


def guesswdcomment(comment):
    guess_flag = 0
    guess_wd: list[str] = []
    guess_ps = 0
    cutin = 0
    cutout = 0
    while true:
        if guess_flag == 0:
            guess_newps = len(comment)
            guess_len = 0
            for initstr in guess_flag_init:
                ps_temp = comment.find(initstr, guess_ps)
                if ps_temp == -1:
                    continue
                else:
                    if ps_temp<guess_newps:
                        guess_newps = ps_temp
                        guess_len = len(initstr)
            if guess_newps == len(comment):
                if not guess_wd:
                    cutin = 0
                    cutout = len(comment)
                    guess_flag = 3
                else:
                    break
            else:
                guess_ps = guess_newps + guess_len
                guess_flag = 1
        elif guess_flag == 1:
            found_temp = false
            found_temp_2 = false
            guess_newps = len(comment)
            for startstr in guess_flag_start_1:
                ps_temp = comment.find(startstr, guess_ps, guess_ps + 20)
                if ps_temp == -1:
                    continue
                else:
                    if ps_temp < guess_newps:
                        found_temp = true
                        guess_newps = ps_temp + len(startstr)
                        guess_flag = 2
            if found_temp:
                guess_ps = guess_newps
                cutin = guess_ps
                continue
            else:
                guess_newps = len(comment)
                for startstr in guess_flag_start_2:
                    ps_temp = comment.find(startstr, guess_ps, guess_ps + 20)
                    if ps_temp == -1:
                        continue
                    else:
                        if ps_temp < guess_newps:
                            found_temp_2 = true
                            guess_newps = ps_temp + len(startstr)
                            guess_flag = 2
            if found_temp_2:
                guess_ps = guess_newps
            cutin = guess_ps
            guess_flag = 2
        elif guess_flag == 2:
            guess_newps = len(comment)
            for endstr in guess_flag_end:
                ps_temp = comment.find(endstr, guess_ps)
                if ps_temp == -1:
                    continue
                else:
                    if ps_temp < guess_newps:
                        guess_newps = ps_temp
            guess_ps = guess_newps
            guess_flag = 3
            cutout = guess_ps
        elif guess_flag == 3:
            found_cut_temp = false
            for dividestr in guess_flag_divide:
                if comment.find(dividestr, cutin, cutout) != -1:
                    found_cut_temp = true
                    for wd in comment[cutin:cutout].split(dividestr):
                        guess_wd.append(wd.strip())
                    break
            if not found_cut_temp:
                guess_wd.append(comment[cutin:cutout].strip())
            guess_flag = 0
        else:
            guess_flag = 0
    return guess_wd


def iscompressedfile(file):
    file = file.lower()
    for rar in rar_file:
        if file.endswith("." + rar):
            return true
    for media in not_rar_file:
        if file.endswith("." + media):
            return false
    return not save_mode


def utfisnumber(uchar):
    return uchar >= u'\u0030' and uchar<=u'\u0039'


def winrardo(folder, file, wd):
    extractstr = " x -y -p" + wd + " \"" + folder + "\\" + file + "\" \"" + folder + "\\\""
    extm = subprocess.call("@\""+loc_winrar+program_rar+"\""+extractstr,shell=true)     
    if extm == 1:    # not rar file
        return 2
    elif extm == 11: # wrong password
        return 1
    elif extm != 0:  # error
        return 1
    else:
        return 0


def z7do(folder, file, wd):
    extractstr = " x -y -p" + wd + " \"" + folder + "\\" + file + "\" -o\"" + folder + "\\\"" 
    extm = subprocess.call("@\""+loc_7z+program_7z+"\""+extractstr,shell=true)
    if extm !=0: # error
        return 1
    else:
        return 0


def unrarfile(folder, file):
    successthisfile = false
    filenameencrypted = true
    if not folder:
        cutpos = file.rindex("\\")
        folder = file[:cutpos]
        file = file[cutpos+1:]
        #print(folder)
        #print(file)
    if enable_rar and file.endswith(".rar"):
        winrarreturn = winrardo(folder, file, passwd[0])
        #print(winrarreturn)
        if winrarreturn == 0:
            #successthisfile = true
            return true
        elif winrarreturn == 2:
            pass
        else:
            getcommentstr = " l -p0 -z" + " \"" + folder + "\\" + file + "\""
            commentnumber = subprocess.call("@\""+loc_winrar+program_rar+"\""+getcommentstr,shell=true)
            #commentnumber = 1
            if commentnumber == 0:
                commentm = subprocess.getstatusoutput("@\""+loc_winrar+program_rar+"\""+getcommentstr)
                if commentm[0] == 0:
                    filenameencrypted = false
                    comment = commentm[1][(commentm[1].index("\n\n")+2):commentm[1].index(folder)]
                    comment = comment[0:comment.rindex("\n\n")]
                    #print(comment)
                    if comment:
                        wdarray = guesswdcomment(comment)
                        print("possible passwords:", wdarray)
                        for wd in wdarray:
                            winrarreturn = winrardo(folder, file, wd)
                            if winrarreturn == 1:
                                continue
                            elif winrarreturn == 0:
                                successthisfile = true
                                break
                            elif winrarreturn == 2:
                                break
                            else:
                                break
            if successthisfile:
                return true
            for index in range(1,len(passwd)):
                winrarreturn = winrardo(folder, file, passwd[index])
                if winrarreturn == 1:
                    continue
                elif winrarreturn == 0:
                    successthisfile = true
                    passwd[0],passwd[index]=passwd[index],passwd[0]
                    break
                elif winrarreturn == 2:
                    break
                else:
                    break
            
    if not successthisfile:
        if enable_7z:
            for index in range(len(passwd)):
                z7return = z7do(folder, file, passwd[index])
                if z7return == 1:
                    continue
                else:
                    successthisfile = true
                    passwd[0],passwd[index]=passwd[index],passwd[0]
                    break
                     
    if not successthisfile: 
        print("failed:"+file)
    return successthisfile


def unrar(folder):
    if os.path.isdir(folder):
        print(folder)
        file_list = os.listdir(folder)
        for file in file_list:
            if os.path.isdir(folder + "/" + file):
                #print(folder +"/"+ file)
                #unrar(folder +"/"+file)
                pass
            else:
                if iscompressedfile(file):
                    if unrarfile(folder, file):
                        if deleteit:
                            os.remove(folder + "/" + file)
    else:
        if iscompressedfile(folder):
            if unrarfile("", folder):
                if deleteit:
                    os.remove(folder)
                  

if __name__ == '__main__':
    if len(sys.argv) <= 1:
        sys.exit(1)
    testrar = os.popen("\""+loc_winrar+program_rar+"\"").read()    
    if not testrar:
       for loc in loc_s_winrar:
           testrar = os.popen("\""+loc+program_rar+"\"").read()
           if testrar:
               loc_winrar = loc
               enable_rar = true
               break
    else:
        enable_rar = true

    test7z = os.popen("\""+loc_7z+program_7z+"\"").read()    
    if not test7z:
       for loc in loc_s_7z:
           test7z = os.popen("\""+loc+program_7z+"\"").read()
           if test7z:
               loc_7z = loc
               enable_7z = true
               break
    else:
        enable_7z = true

    if (not enable_rar) and (not enable_7z):
        print("cannot find winrar and 7-zip")
        sys.exit(1)
    while len(passwd) < 2:
        passwd.append("0")   
    for folder in sys.argv[1:]:
        #print(folder)
        unrar(folder)
    print("finish.")
    #subprocess.call("pause",shell=true)
    sys.exit(0)

以上就是用python批量解压带密码的压缩包的详细内容,更多关于python批量解压压缩包的资料请关注其它相关文章!