为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用密码在python中压缩文件夹?

如何使用密码在python中压缩文件夹?

慕码人8056858 2022-07-19 17:08:50
使用 pyminizip,我可以在 python 中使用密码压缩文件:filepath=r"C:\Users\xxx\Desktop\myFolder\file.txt"import pyminizippyminizip.compress(filepath, None,"output.zip", "password", 0)但是如何将整个文件夹“myFolder”压缩成带有密码的压缩文件?我尝试从路径中删除文件名,但它给出了错误OSError: error in opening C:\Users\xxx\Desktop\myFolder for reading编辑 :以下链接具有压缩目录的功能。但它不会添加密码。https://www.calazan.com/how-to-zip-an-entire-directory-with-python/如果有人可以让我知道是否可以向现有的 zip 文件添加密码,那将解决我的问题。那可能吗?
查看完整描述

2 回答

?
慕婉清6462132

TA贡献1804条经验 获得超2个赞

我终于能够使用 Anupam Chaplot 建议的名为“pyzipper”的库来完成对整个目录(包括所有子文件夹结构和文件)的加密。


这是解决方案:


def zip_folderPyzipper(folder_path, output_path):

    """Zip the contents of an entire folder (with that folder included

    in the archive). Empty subfolders will be included in the archive

    as well.

    """

    parent_folder = os.path.dirname(folder_path)

    # Retrieve the paths of the folder contents.

    contents = os.walk(folder_path)

    try:

        zip_file = pyzipper.AESZipFile('new_test.zip','w',compression=pyzipper.ZIP_DEFLATED,encryption=pyzipper.WZ_AES)

        zip_file.pwd=b'PASSWORD'

        for root, folders, files in contents:

            # Include all subfolders, including empty ones.

            for folder_name in folders:

                absolute_path = os.path.join(root, folder_name)

                relative_path = absolute_path.replace(parent_folder + '\\',

                                                      '')

                print ("Adding '%s' to archive." % absolute_path)

                zip_file.write(absolute_path, relative_path)

            for file_name in files:

                absolute_path = os.path.join(root, file_name)

                relative_path = absolute_path.replace(parent_folder + '\\',

                                                      '')

                print ("Adding '%s' to archive." % absolute_path)

                zip_file.write(absolute_path, relative_path)


        print ("'%s' created successfully." % output_path)


    except IOError as message:

        print (message)

        sys.exit(1)

    except OSError as message:

        print(message)

        sys.exit(1)

    except zipfile.BadZipfile as message:

        print (message)

        sys.exit(1)

    finally:

        zip_file.close()

由于我是 python 新手,我无法详细解释代码。以下是参考资料:


https://pypi.org/project/pyzipper/


https://www.calazan.com/how-to-zip-an-entire-directory-with-python/


在 windows 中提取生成的 ZIP 文件:


右键->解压(加密)


如果直接点击Extract All选项,则会报错


查看完整回答
反对 回复 2022-07-19
?
月关宝盒

TA贡献1772条经验 获得超5个赞

试试这个:首先请在这里检查pynzip。之后尝试一下。


import pyminizip as pyzip


compression = 8

pyzip.compress("test.txt", "test.zip", "Pswrd", compression)

这是如何复制所有目录及其子目录及其文件,然后将其压缩并加密一个zip,使用密码并且不需要关联的备份文件,这里我们将看到如何授权一个mac地址来执行解密。因此,由您决定更改或改进脚本。但基本要素工作得很好。经过大量的研究、测试和思考,我创建了这个有效的解决方案


我的设置:Python 3.8 64:Windows 7 64 上的位:位


使用术语:


第一步,我们需要导入加密模块检查是否支持或其他在这里https://cryptography.io/en/latest/installation/ 命令:pip install cryptography


然后我们将使用这个模块产生的 fernet 对象 https://cryptography.io/en/latest/fernet/


带密码 https://cryptography.io/en/latest/fernet/#using-passwords-with-fernet


和shutil: https ://docs.python.org/3/library/shutil.html 文件second.py:


import os

import re, uuid

import string

import shutil

import zlib

from cryptography.fernet import Fernet

from cryptography.hazmat.primitives import hashes

from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC

import base64

import zipfile


class zipy:

    def __init__(self, pathDir=None):

        """If pathDir optional is none, this script copy all directory in current execution."""

        if pathDir != None:

            if os.path.isdir(pathDir):

                pathDir = pathDir.replace(os.sep, '/')

                if pathDir.endswith('/'):

                    self.root = pathDir

                else:

                    self.root = pathDir + '/'

            else:

                self.root = os.getcwd()+os.sep

                self.root = self.root.replace(os.sep, '/')

        else:

            self.root = os.getcwd()+os.sep

            self.root = self.root.replace(os.sep, '/')

            

        os.chdir(self.root)

        

        self.name = 'sauvegarde'

        self.dirSauvegarde = self.root+self.name

        self.dirSauvegarde = self.dirSauvegarde.replace(os.sep, '/')

        lectureDossier = os.listdir(self.root)

        print(lectureDossier)

        self.path_system = {}

        for element in lectureDossier:

            if os.path.isdir(element):

                if element != '__pycache__':

                    self.path_system[element] = self.root + element + os.sep.replace(os.sep, '/')

                    self.path_system[element] = self.path_system[element].replace(os.sep, '/')

                else:

                    pass

            elif os.path.isfile(element):

                self.path_system[element] = self.root + element

                self.path_system[element] = self.path_system[element].replace(os.sep, '/')

            else:

                pass

        self.zipi = myZip(self.dirSauvegarde)

        

    def save(self):

        """sauvegarde le fichier"""

        self.createDir(self.dirSauvegarde)

        chemin_src = ""

        chemin_dist = ""

        for element in self.path_system:

            if element != self.dirSauvegarde:

                chemin_src = self.root+element

                chemin_dest = self.dirSauvegarde + os.sep + element

                chemin_dest = chemin_dest.replace(os.sep, '/')

                if os.path.isdir(chemin_src):

                    self.copyDir(chemin_src, chemin_dest)

                else:

                    self.copyFile(chemin_src, chemin_dest)

        self.zipi.zip(zip_exist=True)

        self.delDir(self.dirSauvegarde)

    

    def copyDir(self, src, dest):

        try:

            shutil.copytree(src, dest, dirs_exist_ok=True)

        except:

            pass

            

    def copyFile(self, src, dest):

        try:

            shutil.copyfile(src, dest)

        except:

            pass

            

    def createDir(self, dirPath):

        if os.path.isdir(dirPath):

            self.delDir(dirPath)

        else:

            pass

            

        os.makedirs(dirPath, exist_ok=True)

            

    def delDir(self, dir):

        if os.path.isdir(dir):

            if len(os.listdir(dir)) > 0:

                try:

                   print('rmtree')

                   shutil.rmtree(dir, ignore_errors=True)

                except:

                   pass

            else:

                try:

                   os.rmdir(dir)

                except:

                   pass

                   

    def decrypt(self):

        self.zipi.unzip()

        

class myZip:

    def __init__(self, dir):

        self.pathDir = dir

        self.nom = os.path.basename(dir)

        self.pathZip = self.pathDir + '.zip'

        self.crypt = Encryptor()

        

    def zip(self, zip_exist=False):

        if zip_exist == False:

            pass

        else:

            if os.path.isfile(self.pathZip):

                try:

                    os.remove(self.pathZip)

                except:

                    pass

        shutil.make_archive(os.path.splitext(self.pathZip)[0], 'zip', self.pathDir)

        key = self.crypt.key_create()

        #TEST

        self.crypt.file_encrypt(key, self.pathZip, self.pathZip)

        self.crypt.key_write(self.pathZip, key)

        

        

    def unzip(self):

        #TEST

        if self.crypt.checkPass(self.pathZip):

            #print('ok adresse mac autoriser')

            key = self.crypt.key_load(self.pathZip)

            self.crypt.file_decrypt(key, self.pathZip, self.pathZip)

        else:

            print('pas ok adresse mac erroner')


class Encryptor:


    def __init__(self):

        self.salto = None


    def key_create(self):

        password = self.getMac()

        password = bytes(password, encoding="utf-8")


        self.salto = os.urandom(16)

        print(self.salto)

        kdf = PBKDF2HMAC(


            algorithm=hashes.SHA256(),

            length=32,

            salt=self.salto,


            iterations=100,


        )


        key = base64.urlsafe_b64encode(kdf.derive(password))

        return key

            

    def key_write(self, pathZip, key):

        with zipfile.ZipFile(pathZip, 'a') as zip:

            zip.comment = key + bytes(' byMe ', encoding="utf-8") + self.salto

            

        

    def key_load(self, pathZip):

        stri = []

        with zipfile.ZipFile(pathZip, 'a') as zip:

            stri = zip.comment.split(b' byMe ')

            print(stri[0])

            print(stri[1])

            key = stri[0]

            self.salto = stri[1]

        return key

        

    def checkPass(self, pathZip):

        key = base64.urlsafe_b64decode(self.key_load(pathZip))

        salt = self.salto

        mdp = self.getMac()

        mdp = bytes(mdp, encoding="utf-8")

        kdf = PBKDF2HMAC(

            algorithm=hashes.SHA256(),

            length=32,

            salt=salt,

            iterations=100,

        )

        retour = False

        try:

            kdf.verify(mdp, key)

            retour = True

        except:

            retour = False

        return retour

            



    def file_encrypt(self, key, original_file, encrypted_file):

        

        f = Fernet(key)


        with open(original_file, 'rb') as file:

            original = file.read()


        encrypted = f.encrypt(original)


        with open (encrypted_file, 'wb') as file:

            file.write(encrypted)


    def file_decrypt(self, key, encrypted_file, decrypted_file):

        

        f = Fernet(key)


        with open(encrypted_file, 'rb') as file:

            encrypted = file.read()


        decrypted = f.decrypt(encrypted)


        with open(decrypted_file, 'wb') as file:

            file.write(decrypted)

            

    def getMac(self):

        return "".join(re.findall('..', '%012x' % uuid.getnode()))


像这样使用:文件:main.py


from second import zipy


#If the argument is empty, the script will make a copy of the directory being executed, otherwise the script will work and output the zip in the place indicated in argument 

dd = zipy("E:/path")

#or dd = zipy("E:/path/") or dd = zipy() if you give arg, give absolute path

#Save the zip and encrypt it. Change second.py to directly give it a password as an argument 

dd.save()

#decrypt zip

dd.decrypt()


查看完整回答
反对 回复 2022-07-19
  • 2 回答
  • 0 关注
  • 90 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信