python实现按文件夹加密解密其中文件工具
一个使用python实现的按文件夹加密解密其中文件的程序,包含gui界面和较为完善的功能。我们将使用pyqt6来创建gui,使用cryptography库进行加密操作。该程序用到一些模块/库:
pyqt6 库是第三方库,需要安装,用于创建图形用户界面(gui)的库。pyqt6的简介与安装,可参见pyside6 安装和简单界面开发过程详细介绍
cryptography 是第三方库,需要安装,用于加密和解密的库。
sys、os 和 base64是python自带的标准库模块,不需要安装。
运行效果
源码如下:
import sys import os from pyqt6.qtwidgets import (qapplication, qwidget, qpushbutton, qvboxlayout, qhboxlayout, qfiledialog, qlineedit, qlabel, qmessagebox, qprogressbar, qtextedit, qsplitter) from pyqt6.qtcore import qt, qthread, pyqtsignal from pyqt6.qtgui import qfont, qcolor from cryptography.fernet import fernet from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.kdf.pbkdf2 import pbkdf2hmac import base64 class cryptoworker(qthread): progress = pyqtsignal(int) finished = pyqtsignal() error = pyqtsignal(str) status = pyqtsignal(str) # 新增状态信号 def __init__(self, folder, password, mode): super().__init__() self.folder = folder self.password = password self.mode = mode # 'encrypt' or 'decrypt' def run(self): try: key = self.get_key(self.password) fernet = fernet(key) total_files = sum([len(files) for r, d, files in os.walk(self.folder)]) processed_files = 0 self.status.emit(f"开始{'加密' if self.mode == 'encrypt' else '解密'}操作...\n") for root, dirs, files in os.walk(self.folder): for file in files: file_path = os.path.join(root, file) relative_path = os.path.relpath(file_path, self.folder) if self.mode == 'encrypt': if file.endswith('.enc'): self.status.emit(f"跳过已加密文件: {relative_path}") else: self.encrypt_file(fernet, file_path) self.status.emit(f"已加密: {relative_path}") else: # decrypt if not file.endswith('.enc'): self.status.emit(f"跳过未加密文件: {relative_path}") else: self.decrypt_file(fernet, file_path) self.status.emit(f"已解密: {relative_path}") processed_files += 1 self.progress.emit(int(processed_files / total_files * 100)) self.status.emit("\n操作完成!") self.finished.emit() except exception as e: self.error.emit(str(e)) def get_key(self, password): password = password.encode() salt = b'salt_' kdf = pbkdf2hmac( algorithm=hashes.sha256(), length=32, salt=salt, iterations=100000, ) key = base64.urlsafe_b64encode(kdf.derive(password)) return key def encrypt_file(self, fernet, file_path): with open(file_path, 'rb') as f: data = f.read() encrypted = fernet.encrypt(data) encrypted_path = file_path + '.enc' with open(encrypted_path, 'wb') as f: f.write(encrypted) os.remove(file_path) def decrypt_file(self, fernet, file_path): with open(file_path, 'rb') as f: data = f.read() try: decrypted = fernet.decrypt(data) decrypted_path = file_path[:-4] # 移除 '.enc' with open(decrypted_path, 'wb') as f: f.write(decrypted) os.remove(file_path) except: raise exception(f'解密 {file_path} 失败,可能密码错误') class encryptor(qwidget): def __init__(self): super().__init__() self.initui() def initui(self): self.setwindowtitle('文件夹加密器') self.setgeometry(300, 200, 700, 600) main_layout = qvboxlayout() # 上半部分:控制面板 control_panel = qwidget() control_layout = qvboxlayout() # 文件夹选择 folder_layout = qhboxlayout() self.folder_input = qlineedit() folder_button = qpushbutton('选择文件夹') folder_button.clicked.connect(self.select_folder) folder_layout.addwidget(self.folder_input) folder_layout.addwidget(folder_button) control_layout.addlayout(folder_layout) # 密码输入 password_layout = qhboxlayout() password_label = qlabel('密码:') self.password_input = qlineedit() self.password_input.setechomode(qlineedit.echomode.password) password_layout.addwidget(password_label) password_layout.addwidget(self.password_input) control_layout.addlayout(password_layout) # 进度条 self.progress_bar = qprogressbar() control_layout.addwidget(self.progress_bar) # 加密解密按钮 button_layout = qhboxlayout() encrypt_button = qpushbutton('加密') decrypt_button = qpushbutton('解密') encrypt_button.clicked.connect(lambda: self.process_folder('encrypt')) decrypt_button.clicked.connect(lambda: self.process_folder('decrypt')) button_layout.addwidget(encrypt_button) button_layout.addwidget(decrypt_button) control_layout.addlayout(button_layout) control_panel.setlayout(control_layout) main_layout.addwidget(control_panel) # 分割线 splitter = qsplitter(qt.orientation.vertical) # 注意事项面板 notice_panel = qwidget() notice_layout = qvboxlayout() notice_label = qlabel("注意事项:") notice_label.setfont(qfont("arial", 12, qfont.weight.bold)) notice_label.setstylesheet("color: red;") notice_text = qtextedit() notice_text.setplaintext( "1. 请确保记住密码,否则将无法解密文件。\n" "2. 请慎重操作!该程序会直接在原文件夹中操作,谨防误操作。\n" "3. 加密后删除原文件,解密后删除加密文件。加密后的文件会有 .enc 扩展名。\n" "4. 本程序支持加密/解密文件夹中的所有文件。\n" "5. 已加密的文件不会被重复加密,未加密的文件不会被解密。" ) notice_text.setreadonly(true) notice_text.setfont(qfont("arial", 11)) notice_text.setstylesheet("color: #d32f2f;") # 深红色 notice_layout.addwidget(notice_label) notice_layout.addwidget(notice_text) notice_panel.setlayout(notice_layout) # 日志面板 log_panel = qwidget() log_layout = qvboxlayout() log_label = qlabel("处理日志:") #log_label.setfont(qfont("arial", 10, qfont.weight.bold)) self.log_text = qtextedit() self.log_text.setreadonly(true) #self.log_text.setfont(qfont("arial", 10)) log_layout.addwidget(log_label) log_layout.addwidget(self.log_text) log_panel.setlayout(log_layout) # 添加面板到分割器 splitter.addwidget(notice_panel) splitter.addwidget(log_panel) main_layout.addwidget(splitter) self.setlayout(main_layout) def select_folder(self): folder = qfiledialog.getexistingdirectory(self, "选择文件夹") self.folder_input.settext(folder) def process_folder(self, mode): folder = self.folder_input.text() password = self.password_input.text() if not folder or not password: qmessagebox.warning(self, '警告', '请选择文件夹并输入密码') return # 清空日志 self.log_text.clear() self.worker = cryptoworker(folder, password, mode) self.worker.progress.connect(self.update_progress) self.worker.finished.connect(self.process_finished) self.worker.error.connect(self.process_error) self.worker.status.connect(self.update_log) # 连接状态信号 self.worker.start() def update_progress(self, value): self.progress_bar.setvalue(value) def update_log(self, message): self.log_text.append(message) def process_finished(self): qmessagebox.information(self, '成功', '操作完成') self.progress_bar.setvalue(0) def process_error(self, error_msg): qmessagebox.critical(self, '错误', f'发生错误:{error_msg}') self.progress_bar.setvalue(0) self.log_text.append(f"\n错误: {error_msg}") if __name__ == '__main__': app = qapplication(sys.argv) ex = encryptor() ex.show() sys.exit(app.exec())
到此这篇关于python如何实现按文件夹加密解密其中文件的文章就介绍到这了,更多相关python加密解密文件内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论