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


Posted in Python onMay 31, 2021

项目地址:

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批量解压压缩包的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python发送form-data请求及拼接form-data内容的方法
Mar 05 Python
使用Python实现windows下的抓包与解析
Jan 15 Python
Python实现k-means算法
Feb 23 Python
python把数组中的数字每行打印3个并保存在文档中的方法
Jul 17 Python
Python多线程原理与用法实例剖析
Jan 22 Python
对python dataframe逻辑取值的方法详解
Jan 30 Python
python GUI库图形界面开发之PyQt5信号与槽事件处理机制详细介绍与实例解析
Mar 08 Python
Python 改变数组类型为uint8的实现
Apr 09 Python
python中如何写类
Jun 29 Python
Python基于unittest实现测试用例执行
Nov 25 Python
Python hashlib和hmac模块使用方法解析
Dec 08 Python
Python实战实现爬取天气数据并完成可视化分析详解
Jun 16 Python
变长双向rnn的正确使用姿势教学
如何在Python项目中引入日志
Tensorflow与RNN、双向LSTM等的踩坑记录及解决
Python数据类型最全知识总结
May 31 #Python
教你怎么用Python操作MySql数据库
Django集成富文本编辑器summernote的实现步骤
Python基础知识学习之类的继承
May 31 #Python
You might like
ThinkPHP CURD方法之page方法详解
2014/06/18 PHP
PHP使用Pear发送邮件(Windows环境)
2016/01/05 PHP
PHP中include/require/include_once/require_once使用心得
2016/08/28 PHP
PHPExcel 修改已存在Excel的方法
2018/05/03 PHP
ThinkPHP 3.2.3实现加减乘除图片验证码
2018/12/05 PHP
javascript判断用户浏览器插件安装情况的代码
2011/01/01 Javascript
node.js中的buffer.Buffer.isBuffer方法使用说明
2014/12/14 Javascript
jQuery中slice()方法用法实例
2015/01/07 Javascript
jquery实现右键菜单插件
2015/03/29 Javascript
AngularJS中isolate scope的用法分析
2016/11/22 Javascript
javascript自执行函数
2017/02/10 Javascript
浅谈react-native热更新react-native-pushy集成遇到的问题
2017/09/30 Javascript
Element中的Cascader(级联列表)动态加载省\市\区数据的方法
2019/03/27 Javascript
vue component 中引入less文件报错 Module build failed
2019/04/17 Javascript
JavaScript函数式编程(Functional Programming)组合函数(Composition)用法分析
2019/05/22 Javascript
vue实现表单录入小案例
2019/09/27 Javascript
微信小程序利用button控制条件标签的变量问题
2020/03/15 Javascript
浅谈js数组splice删除某个元素爬坑
2020/10/14 Javascript
vue mvvm数据响应实现
2020/11/11 Javascript
python网络编程学习笔记(四):域名系统
2014/06/09 Python
让Python代码更快运行的5种方法
2015/06/21 Python
python正则表达式及使用正则表达式的例子
2018/01/22 Python
Django项目实战之用户头像上传与访问的示例
2018/04/21 Python
Python使用进程Process模块管理资源
2020/03/05 Python
基于 HTML5 的 WebGL 3D 版俄罗斯方块的示例代码
2018/05/28 HTML / CSS
写给爸爸的道歉信
2014/01/15 职场文书
地球一小时宣传标语
2014/06/24 职场文书
公司委托书格式
2014/08/01 职场文书
单位委托书怎么写
2014/08/02 职场文书
学习朴航瑛老师爱岗敬业先进事迹思想汇报
2014/09/17 职场文书
2014离婚协议书范文(3篇)
2014/11/29 职场文书
医院营销工作计划
2015/01/16 职场文书
交警失职检讨书
2015/01/26 职场文书
试用期转正工作总结2015
2015/05/28 职场文书
《角的初步认识》教学反思
2016/02/17 职场文书
小程序实现筛子抽奖
2021/05/26 Javascript