用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实现的简单文本类游戏实例
Apr 28 Python
Python的Urllib库的基本使用教程
Apr 30 Python
举例详解Python中循环语句的嵌套使用
May 14 Python
python类继承用法实例分析
May 27 Python
Python爬虫_城市公交、地铁站点和线路数据采集实例
Jan 10 Python
Python面向对象类编写细节分析【类,方法,继承,超类,接口等】
Jan 05 Python
linux中如何使用python3获取ip地址
Jul 15 Python
Django框架静态文件使用/中间件/禁用ip功能实例详解
Jul 22 Python
解决Django提交表单报错:CSRF token missing or incorrect的问题
Mar 13 Python
Python爬虫之Selenium实现键盘事件
Dec 04 Python
Github 使用python对copilot做些简单使用测试
Apr 14 Python
python使用shell脚本创建kafka连接器
Apr 29 Python
变长双向rnn的正确使用姿势教学
如何在Python项目中引入日志
Tensorflow与RNN、双向LSTM等的踩坑记录及解决
Python数据类型最全知识总结
May 31 #Python
教你怎么用Python操作MySql数据库
Django集成富文本编辑器summernote的实现步骤
Python基础知识学习之类的继承
May 31 #Python
You might like
PHP代码优化的53个细节
2014/03/03 PHP
PHP+MySQL删除操作实例
2015/01/21 PHP
js代码实现微博导航栏
2015/07/30 PHP
PHP实现的解汉诺塔问题算法示例
2018/08/06 PHP
ThinkPHP5&amp;5.1实现验证码的生成、使用及点击刷新功能示例
2020/02/07 PHP
CL vs ForZe BO5 第四场 2.13
2021/03/10 DOTA
[Web]防止用户复制页面内容和另存页面的方法
2009/02/06 Javascript
jQuery实现拖动调整表格单元格大小的代码实例
2015/01/13 Javascript
NodeJS学习笔记之Connect中间件应用实例
2015/01/27 NodeJs
js鼠标单击和双击事件冲突问题的快速解决方法
2016/07/11 Javascript
JS获取鼠标相对位置的方法
2016/09/20 Javascript
AngularJS指令与控制器之间的交互功能示例
2016/12/14 Javascript
Bootstrap datepicker日期选择器插件使用详解
2017/07/26 Javascript
原生js中ajax访问的实例详解
2017/09/19 Javascript
vue实现nav导航栏的方法
2017/12/13 Javascript
解决vue中修改了数据但视图无法更新的情况
2018/08/27 Javascript
Typescript 中的 interface 和 type 到底有什么区别详解
2019/06/18 Javascript
详解利用nodejs对本地json文件进行增删改查
2019/09/20 NodeJs
JavaScript算法学习之冒泡排序和选择排序
2019/11/02 Javascript
Python的Django框架中URLconf相关的一些技巧整理
2015/07/18 Python
Python进阶学习之特殊方法实例详析
2017/12/01 Python
python3利用Dlib19.7实现人脸68个特征点标定
2018/02/26 Python
德国净水壶和滤芯品牌:波尔德PearlCo(家用净水器)
2020/04/29 全球购物
如何查询Oracle数据库中已经创建的索引
2013/10/11 面试题
个人社会实践自我鉴定
2014/03/24 职场文书
《梅花魂》教学反思
2014/04/30 职场文书
数控专业毕业生求职信
2014/06/12 职场文书
个人委托书怎么写
2014/09/17 职场文书
法律专业大学生职业生涯规划书:向目标一步步迈进
2014/09/22 职场文书
2014年师德师风自我剖析材料
2014/09/27 职场文书
2014年团支书工作总结
2014/11/14 职场文书
小学班主任心得体会
2016/01/07 职场文书
《詹天佑》教学反思
2016/02/20 职场文书
小学二年级语文教学反思
2016/03/03 职场文书
html5表单的required属性使用
2021/07/07 HTML / CSS
mysql 8.0.27 绿色解压版安装教程及配置方法
2022/04/20 MySQL