用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爬虫框架Scrapy安装使用步骤
Apr 01 Python
Python with的用法
Aug 22 Python
python使用webbrowser浏览指定url的方法
Apr 04 Python
Python基于checksum计算文件是否相同的方法
Jul 09 Python
python实现12306火车票查询器
Apr 20 Python
使用Python从零开始撸一个区块链
Mar 14 Python
对pandas中to_dict的用法详解
Jun 05 Python
python 将print输出的内容保存到txt文件中
Jul 17 Python
python list格式数据excel导出方法
Oct 31 Python
Python检查图片是否损坏及图片类型是否正确过程详解
Sep 30 Python
pytorch下大型数据集(大型图片)的导入方式
Jan 08 Python
python3.7.2 tkinter entry框限定输入数字的操作
May 22 Python
变长双向rnn的正确使用姿势教学
如何在Python项目中引入日志
Tensorflow与RNN、双向LSTM等的踩坑记录及解决
Python数据类型最全知识总结
May 31 #Python
教你怎么用Python操作MySql数据库
Django集成富文本编辑器summernote的实现步骤
Python基础知识学习之类的继承
May 31 #Python
You might like
php 批量生成html,txt文件的实现代码
2013/06/26 PHP
php setcookie函数的参数说明及其用法
2014/04/20 PHP
PHP SPL标准库之接口(Interface)详解
2015/05/11 PHP
提交表单后 PHP获取提交内容的实现方法
2016/05/25 PHP
php中引用&amp;的用法分析【变量引用,函数引用,对象引用】
2016/12/12 PHP
基于JQuery的类似新浪微博展示信息效果的代码
2012/07/23 Javascript
javascript和HTML5利用canvas构建猜牌游戏实现算法
2013/07/17 Javascript
js open() 与showModalDialog()方法使用介绍
2013/09/10 Javascript
js图片向右一张张滚动效果实例代码
2013/11/23 Javascript
获取鼠标在div中的相对位置的实现代码
2013/12/30 Javascript
一个不错的js html页面倒计时可精确到秒
2014/10/22 Javascript
在easyUI开发中,出现jquery.easyui.min.js函数库问题的解决办法
2015/09/11 Javascript
jquery validate.js表单验证入门实例(附源码)
2015/11/10 Javascript
KnockoutJS 3.X API 第四章之click绑定
2016/10/10 Javascript
jQuery实现验证码功能
2017/03/17 Javascript
基于vue的换肤功能的示例代码
2017/10/10 Javascript
vue实现商城购物车功能
2017/11/27 Javascript
浅谈React Event实现原理
2018/09/20 Javascript
小程序关于请求同步的总结
2019/05/05 Javascript
CountUp.js实现数字滚动增值效果
2019/10/17 Javascript
vuex state中的数组变化监听实例
2019/11/06 Javascript
node.js中process进程的概念和child_process子进程模块的使用方法示例
2020/02/11 Javascript
Python实现提取谷歌音乐搜索结果的方法
2015/07/10 Python
python开发之基于thread线程搜索本地文件的方法
2015/11/11 Python
Python argv用法详解
2016/01/08 Python
python3基于TCP实现CS架构文件传输
2018/07/28 Python
Opencv+Python 色彩通道拆分及合并的示例
2018/12/08 Python
python文件拆分与重组实例
2018/12/10 Python
python 串行执行和并行执行实例
2020/04/30 Python
双语教学实施方案
2014/03/23 职场文书
政协调研汇报材料
2014/08/15 职场文书
2014年财务工作总结与计划
2014/12/08 职场文书
学生考试舞弊检讨书
2015/01/01 职场文书
小学端午节活动总结
2015/02/11 职场文书
《落花生》教学反思
2016/02/16 职场文书
mybatis调用sqlserver存储过程返回结果集的方法
2021/05/08 SQL Server