Python如何实现按文件夹加密解密其中文件
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加密解密文件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
python opencv鼠标画矩形框之cv2.rectangle()函数
鼠标操作属于用户接口设计,以前一直使用Qt来做,但是如果只需要简单的鼠标,键盘操作,直接调用opencv库的函数也未尝不可,下面这篇文章主要给大家介绍了关于python opencv鼠标画矩形框cv2.rectangle()函数的相关资料,需要的朋友可以参考下2021-10-10
PySide(PyQt)使用QPropertyAnimation制作动态界面的示例代码
文章介绍了如何使用PySide或PyQt的QPropertyAnimation类来创建动态界面效果,感兴趣的朋友一起看看吧2025-03-03
Python使用Windows API创建窗口示例【基于win32gui模块】
这篇文章主要介绍了Python使用Windows API创建窗口操作,结合实例形式分析了Python基于win32gui模块调用Windows API创建窗口具体操作步骤与相关实现技巧,需要的朋友可以参考下2018-05-05


最新评论