zip, rar, 7z 的解压缩,python 实现

发布时间 2023-07-07 10:58:05作者: journeyer_xsh

zip

标准库中的zipfile无法创建加密的zip文件,这里使用pyzipper

pip install pyzipper

pyzipper的github:https://github.com/danifus/pyzipper

pyzipper除了部分自己新增的api,其他的api基本上和zipfile一致,用法基本相同。

import pyzipper
secret_password = b'lost art of keeping a secret'
with pyzipper.AESZipFile('new_test.zip',
                         'w',
                         compression=pyzipper.ZIP_LZMA,
                         encryption=pyzipper.WZ_AES) as zf:
    zf.setpassword(secret_password)
    zf.writestr('test.txt', "What ever you do, don't tell anyone!")

with pyzipper.AESZipFile('new_test.zip') as zf:
    zf.setpassword(secret_password)
    my_secrets = zf.read('test.txt')


import pyzipper
secret_password = b'lost art of keeping a secret'
with pyzipper.AESZipFile('new_test.zip',
                         'w',
                         compression=pyzipper.ZIP_LZMA) as zf:
    zf.setpassword(secret_password)
    zf.setencryption(pyzipper.WZ_AES, nbits=128)  # 默认是256
    zf.writestr('test.txt', "What ever you do, don't tell anyone!")

with pyzipper.AESZipFile('new_test.zip') as zf:
    zf.setpassword(secret_password)
    my_secrets = zf.read('test.txt')


def check_zip_encrypted(file: str):
    '''
    name:
    des: 检测zip格式压缩保是否加密
    param {传入的文件名}
    return {True:文件加密 False:文件没加密}
    '''
    zf = pyzipper.ZipFile(file)
    is_encrypted_bool = False
    for zinfo in zf.infolist():
        is_encrypted = zinfo.flag_bits & 0x1
        if is_encrypted:
            is_encrypted_bool = True
            break
    return is_encrypted_bool
~~

# rar
## rarfile
~~~python
pip install rafile

只支持解压,压缩不支持

def check_rar_encrypted(file: str) -> bool:
    """检查rar是否需要密码"""
    import rarfile as rarf
    with rarf.RarFile(file) as rf:
        encrypted_files = [f for f in rf.infolist() if f.needs_password()]
        if len(encrypted_files) > 0:
            return True
        else:
            return False

unrar

pip install unrar

unrar的github:https://github.com/matiasb/python-unrar

安装unrar后仍然提示Couldn't find path to unrar library
Win:

  1. 先到RARLab官方下载库文件,http://www.rarlab.com/rar/UnRARDLL.exe ,然后安装;
  2. 安装最好选择默认路径,一般在 C:\Program Files (x86)\UnrarDLL\ 目录下;
  3. 将UnRAR.dll复制到代码的运行目录下,运行代码,不行则执行 4.
  4. 添加环境变量,在系统变量(注意不是用户变量)中 新建,变量名输入 UNRAR_LIB_PATH ,变量值要特别注意!如果你是64位系统,就输入 C:\Program Files (x86)\UnrarDLL\x64\UnRAR64.dll,如果是32位系统就输入 C:\Program Files (x86)\UnrarDLL\UnRAR.dll ,这个从unrar安装目录的内容也能看出来它是区分64和32位的。
  5. 确定保存环境变量后,重启你的PyCharm,代码不变,再运行就不会出错了。这个时候依赖库已经添加到系统环境中。

Linux:

  1. 下载的是源代码:http://www.rarlab.com/rar/unrarsrc-5.4.5.tar.gz ,也就是RARLab官网下载列表中的 UnRAR Source,可以下载到最新版本;
  2. 下载完后解压,cd unrar mu后,使用 make lib 命令将会自动编译库文件,编译完成后,再使用 make install-lib 命令产生 libunrar.so 文件(一般在 /usr/lib 目录下面);
  3. 最后,你仍然需要设置Linux系统的环境变量,找到 /etc 目录下的 profile 文件,当然你可以直接使用 vim /etc/profile 命令来编辑(有WinSCP这种远程访问目录的工具更方便),在 profile 文件末尾加上 export UNRAR_LIB_PATH=/usr/lib/libunrar.so ,别把我这句话的逗号加进去了。成功保存后再使用 source /etc/profile 命令使变量生效。
# 示例代码
if os.name == 'nt':
    pass
else:
    os.environ['UNRAR_LIB_PATH'] = './libunrar.so'

from unrar import rarfile
outpath = ''
pwd = '123'
rar_fp = rarfile.RarFile(zip_filename)
filename_list = [file.filename for file in rar_fp.infolist()]
rar_fp.extractall(path=outpath, members=filename_list , pwd=pwd)

7z

import os
improt tempfile
import py7zr

pwd = ''
old_path = ''
new_path = ''
# 解压
file_list = zin.list()
temp_dir = tempfile.mkdtemp()  # 创建临时文件夹
targets = [file.filename for file in file_list file.filename]
with py7zr.SevenZipFile(old_path, 'r', password=pwd)as zin:  # 读取对象
    zin.extract(path=temp_dir, targets=targets)

# 压缩
with py7zr.SevenZipFile(new_path, 'w', password=pwd) as zout:
    if pwd is not None:
        zout.set_encrypted_header(True)
    for foldername, subfolders, filenames in os.walk(dir_path):
        for filename in filenames:
            file_path = os.path.join(foldername, filename)
            zout.write(file_path, arcname=os.path.relpath(file_path, start=dir_path))


def check_7z_encrypted(file_path) -> bool:
    """检查7z是否需要密码"""
    try:
        with py7zr.SevenZipFile(file_path, mode='r', password=None) as archive:
            # 检查文件列表以验证是否需要密码
            archive.getnames()
            return False  
    except py7zr.exceptions.PasswordRequired:
        return True  

参考资料

https://blog.csdn.net/ysy950803/article/details/52939708
https://www.cnblogs.com/dacyuan/p/14081693.html