用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自动安装pip
Apr 24 Python
Python中用Decorator来简化元编程的教程
Apr 13 Python
Python爬取附近餐馆信息代码示例
Dec 09 Python
python方向键控制上下左右代码
Jan 20 Python
python高级特性和高阶函数及使用详解
Oct 17 Python
DES加密解密算法之python实现版(图文并茂)
Dec 06 Python
基于wxPython的GUI实现输入对话框(1)
Feb 27 Python
Django框架文件上传与自定义图片上传路径、上传文件名操作分析
May 10 Python
python 实现在tkinter中动态显示label图片的方法
Jun 13 Python
python中如何使用insert函数
Jan 09 Python
python opencv 实现读取、显示、写入图像的方法
Jun 08 Python
pytorch使用horovod多gpu训练的实现
Sep 09 Python
变长双向rnn的正确使用姿势教学
如何在Python项目中引入日志
Tensorflow与RNN、双向LSTM等的踩坑记录及解决
Python数据类型最全知识总结
May 31 #Python
教你怎么用Python操作MySql数据库
Django集成富文本编辑器summernote的实现步骤
Python基础知识学习之类的继承
May 31 #Python
You might like
PHP英文字母大小写转换函数小结
2014/05/03 PHP
js 数组实现一个类似ruby的迭代器
2009/10/27 Javascript
jQuery chili图片远处放大插件
2009/11/30 Javascript
一些实用的jQuery代码片段收集
2011/07/12 Javascript
js 触发select onchange事件代码
2014/03/20 Javascript
node.js不得不说的12点内容
2014/07/14 Javascript
JS遍历Json字符串中键值对先转成JSON对象再遍历
2014/08/15 Javascript
JavaScript sub方法入门实例(把字符串显示为下标)
2014/10/17 Javascript
JavaScript中字符串(string)转json的2种方法
2015/06/25 Javascript
jQuery在线选座位插件seat-charts特效代码分享
2015/08/27 Javascript
ES6中Proxy代理用法实例浅析
2017/04/06 Javascript
javascript简单写的判断电话号码实例
2017/05/24 Javascript
bootstrap动态添加面包屑(breadcrumb)及其响应事件的方法
2017/05/25 Javascript
关于vue-resource报错450的解决方案
2017/07/24 Javascript
jQuery+HTML5实现WebGL高性能烟花绽放动画效果【附demo源码下载】
2017/08/18 jQuery
iconfont的三种使用方式详解
2018/08/05 Javascript
vue-cli项目修改文件热重载失效的解决方法
2018/09/19 Javascript
jQuery pjax 应用简单示例
2018/09/20 jQuery
Angular(5.2-&gt;6.1)升级小结
2018/12/27 Javascript
Python删除指定目录下过期文件的2个脚本分享
2014/04/10 Python
Python获取邮件地址的方法
2015/07/10 Python
wxpython中Textctrl回车事件无效的解决方法
2016/07/21 Python
python利用smtplib实现QQ邮箱发送邮件
2020/05/20 Python
在django中,关于session的通用设置方法
2019/08/06 Python
python中读入二维csv格式的表格方法详解(以元组/列表形式表示)
2020/04/24 Python
3分钟看懂Python后端必须知道的Django的信号机制
2020/07/26 Python
Django Model层F,Q对象和聚合函数原理解析
2020/11/12 Python
Html5大文件断点续传实现方法
2015/12/05 HTML / CSS
美国男士内衣品牌:Tommy John
2017/12/22 全球购物
墨西哥网上超市:Superama
2018/07/10 全球购物
自考生自我鉴定范文
2013/10/01 职场文书
投资合作协议书
2014/04/17 职场文书
应届生求职信范文
2014/06/30 职场文书
2014流动人口计划生育工作总结
2014/12/20 职场文书
干部考核工作总结2015
2015/07/24 职场文书
Python djanjo之csrf防跨站攻击实验过程
2021/05/14 Python