《 Python程序设计项目案例》— Python给文件加密小程序代码PyQT交互界面

《 Python程序设计项目案例》— Python给文件加密小程序代码PyQT交互界面

项目背景

Windows给文件夹加密,一般通过设置文件夹安全权限或者压缩文件密码,或者通过BitLocker加密整个磁盘,再者就需要借助其他第三方软件了。
本文使用Python的第三方包cryptography为基础给文件(夹)加密,并使用PyQT设计了方便使用的交互界面。

项目源码

# -*- coding: utf-8 -*-
"""==============================
#@Project : QtFliePs
#@File    : QtFliePs
#@Software: PyCharm
#@Author  : Echo
#@Email   : [email protected]
#@Date    : 2024/12/26 09:09
#@Desc    : 2贰进制微信公众号——文件加密
=============================="""
import os
import hashlib
import base64
import time

from cryptography.fernet import Fernet
from PyQt5.QtWidgets import (
    QApplication,
    QMainWindow,
    QWidget,
    QLabel,
    QLineEdit,
    QPushButton,
    QFileDialog,
    QMessageBox,
    QVBoxLayout,
    QHBoxLayout,
    QScrollArea
)
from PyQt5.QtGui import QDragEnterEvent, QDropEvent
from PyQt5.QtCore import Qt


class DropZone(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setAcceptDrops(True)
        self.text = QLabel(self)
        self.text.setAlignment(Qt.AlignCenter)
        self.text.setText("将文件夹拖拽至此")
        self.setStyleSheet("border: 2px dashed #333;")
        self.drag_zone = None

    def dragEnterEvent(self, event: QDragEnterEvent):
        if event.mimeData().hasUrls():
            event.acceptProposedAction()

    def dropEvent(self, event: QDropEvent):
        mime_data = event.mimeData()
        if mime_data.hasUrls():
            urls = mime_data.urls()
            if urls:
                folder_path = urls[0].toLocalFile()
                if os.path.isdir(folder_path):
                    self.text.setText(folder_path)
                else:
                    QMessageBox.warning(self, '警告', '请拖拽文件夹')


class CustomWidget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.drag_zone = DropZone(self)
        layout = QVBoxLayout(self)
        layout.addWidget(self.drag_zone)

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('文件夹加密工具')
        self.setGeometry(100, 100, 400, 300)

        main_widget = QWidget()
        self.setCentralWidget(main_widget)
        layout = QVBoxLayout(main_widget)

        # 加密区域
        self.encrypt_zone = self.create_action_zone('加密', '拖拽文件夹至此进行加密')
        layout.addWidget(self.encrypt_zone)

        # 解密区域
        self.decrypt_zone = self.create_action_zone('解密', '拖拽文件夹至此进行解密')
        layout.addWidget(self.decrypt_zone)

        # 密钥输入
        self.key_input = QLineEdit(self)
        self.key_input.setPlaceholderText('输入密钥字符串')
        layout.addWidget(self.key_input)

        # 开始按钮
        self.start_button = QPushButton('开始', self)
        self.start_button.clicked.connect(self.start_action)
        layout.addWidget(self.start_button)

        # 状态显示
        self.status_label = QLabel('', self)
        layout.addWidget(self.status_label)

    def create_action_zone(self, title, hint):
        zone = CustomWidget()
        zone.drag_zone.text.setText(hint)
        return zone

    def generate_fernet_key(self):
        user_input = self.key_input.text().strip()
        if not user_input:
            return Fernet.generate_key()
        hash_object = hashlib.sha256(user_input.encode('utf-8'))
        hash_bytes = hash_object.digest()
        fernet_key = base64.urlsafe_b64encode(hash_bytes)
        return fernet_key
    
    def encrypt_folder(self, folder_path, key):
        if not folder_path:
            return False

        # key = self.generate_fernet_key()
        cipher = Fernet(key)

        try:
            for root, dirs, files in os.walk(folder_path):
                for file in files:
                    file_path = os.path.join(root, file)
                    with open(file_path, 'rb') as f:
                        data = f.read()
                    encrypted_data = cipher.encrypt(data)
                    encrypted_file = os.path.join(root, f"{file}.encrypted")
                    with open(encrypted_file, 'wb') as f:
                        f.write(encrypted_data)
                    os.remove(file_path)
            return True
        except Exception as e:
            return False

    def decrypt_folder(self, folder_path, key):
        if not folder_path:
            return False

        # key = self.generate_fernet_key()
        cipher = Fernet(key)

        try:
            for root, dirs, files in os.walk(folder_path):
                for file in files:
                    if file.endswith('.encrypted'):
                        encrypted_file = os.path.join(root, file)
                        original_file = os.path.join(root, file[:-9])
                        with open(encrypted_file, 'rb') as f:
                            encrypted_data = f.read()
                        decrypted_data = cipher.decrypt(encrypted_data)
                        with open(original_file, 'wb') as f:
                            f.write(decrypted_data)
                        os.remove(encrypted_file)
            return True
        except Exception as e:
            return False

    def start_action(self):
        try:
            current_zone = None
            if self.encrypt_zone.drag_zone.text.text() != '拖拽文件夹至此进行加密':
                current_zone = '加密'
            elif self.decrypt_zone.drag_zone.text.text() != '拖拽文件夹至此进行解密':
                current_zone = '解密'
            print(current_zone)
            if not current_zone:
                QMessageBox.warning(self, '警告', '请先选择文件夹')
                return

            if current_zone == '加密':
                folder_path = self.encrypt_zone.drag_zone.text.text()
            else:
                folder_path = self.decrypt_zone.drag_zone.text.text()
            print(folder_path)

            if not os.path.isdir(folder_path):
                QMessageBox.warning(self, '警告', '请选择有效的文件夹')
                return

            try:
                key = self.generate_fernet_key()
            except Exception as e:
                QMessageBox.warning(self, '警告', f'密钥处理失败:{str(e)}')
                return

            if current_zone == '加密':
                success = self.encrypt_folder(folder_path, key)
            else:
                success = self.decrypt_folder(folder_path, key)

            if success:
                # self.status_label.setText(f'{current_zone}完成')
                QMessageBox.information(self, '提示', f'{current_zone}已完成')
                # time.sleep(5)
                self.initUI()
            else:
                self.status_label.setText(f'{current_zone}失败')
        except Exception as e:
            print(f"An error occurred: {e}")

def main():
    import sys
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()


posted @ 2025-03-29 22:44  某不知名搬砖选手  阅读(2)  评论(0)    收藏  举报  来源