最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python如何實(shí)現(xiàn)按文件夾加密解密其中文件

 更新時(shí)間:2025年04月25日 11:11:52   作者:學(xué)習(xí)&實(shí)踐愛(ài)好者  
這篇文章主要為大家詳細(xì)介紹了一個(gè)使用Python實(shí)現(xiàn)的按文件夾加密解密其中文件的程序,包含GUI界面和較為完善的功能,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

Python實(shí)現(xiàn)按文件夾加密解密其中文件工具

一個(gè)使用Python實(shí)現(xiàn)的按文件夾加密解密其中文件的程序,包含GUI界面和較為完善的功能。我們將使用PyQt6來(lái)創(chuàng)建GUI,使用cryptography庫(kù)進(jìn)行加密操作。該程序用到一些模塊/庫(kù):

PyQt6 庫(kù)是第三方庫(kù),需要安裝,用于創(chuàng)建圖形用戶界面(GUI)的庫(kù)。PyQt6的簡(jiǎn)介與安裝,可參見(jiàn)Pyside6 安裝和簡(jiǎn)單界面開(kāi)發(fā)過(guò)程詳細(xì)介紹

cryptography 是第三方庫(kù),需要安裝,用于加密和解密的庫(kù)。

sys、os 和 base64是Python自帶的標(biāo)準(zhǔn)庫(kù)模塊,不需要安裝。

運(yùn)行效果

源碼如下:

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)  # 新增狀態(tài)信號(hào)
 
    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"開(kāi)始{'加密' 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"跳過(guò)已加密文件: {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"跳過(guò)未加密文件: {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} 失敗,可能密碼錯(cuò)誤')
 
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)
 
        # 進(jìn)度條
        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)
 
        # 注意事項(xiàng)面板
        notice_panel = QWidget()
        notice_layout = QVBoxLayout()
        notice_label = QLabel("注意事項(xiàng):")
        notice_label.setFont(QFont("Arial", 12, QFont.Weight.Bold))
        notice_label.setStyleSheet("color: red;")
        notice_text = QTextEdit()
        notice_text.setPlainText(
            "1. 請(qǐng)確保記住密碼,否則將無(wú)法解密文件。\n"
            "2. 請(qǐng)慎重操作!該程序會(huì)直接在原文件夾中操作,謹(jǐn)防誤操作。\n"
            "3. 加密后刪除原文件,解密后刪除加密文件。加密后的文件會(huì)有 .enc 擴(kuò)展名。\n"
            "4. 本程序支持加密/解密文件夾中的所有文件。\n"
            "5. 已加密的文件不會(huì)被重復(fù)加密,未加密的文件不會(huì)被解密。"
        )
        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, '警告', '請(qǐng)選擇文件夾并輸入密碼')
            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)  # 連接狀態(tài)信號(hào)
        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, '錯(cuò)誤', f'發(fā)生錯(cuò)誤:{error_msg}')
        self.progress_bar.setValue(0)
        self.log_text.append(f"\n錯(cuò)誤: {error_msg}")
 
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Encryptor()
    ex.show()
    sys.exit(app.exec())

到此這篇關(guān)于Python如何實(shí)現(xiàn)按文件夾加密解密其中文件的文章就介紹到這了,更多相關(guān)Python加密解密文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • django admin 自定義替換change頁(yè)面模板的方法

    django admin 自定義替換change頁(yè)面模板的方法

    今天小編就為大家分享一篇django admin 自定義替換change頁(yè)面模板的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-08-08
  • 使用Python實(shí)現(xiàn)圖片位深轉(zhuǎn)換終極指南

    使用Python實(shí)現(xiàn)圖片位深轉(zhuǎn)換終極指南

    圖片位深(Bit Depth)指的是每個(gè)像素用于表示顏色的位數(shù),常見(jiàn)的位深包括,1位,8位,24位和32位,本文主要介紹了如何使用Python實(shí)現(xiàn)圖片位深轉(zhuǎn)換,感興趣的小伙伴可以了解下
    2025-07-07
  • Python實(shí)現(xiàn)批量檢測(cè)HTTP服務(wù)的狀態(tài)

    Python實(shí)現(xiàn)批量檢測(cè)HTTP服務(wù)的狀態(tài)

    本文給大家分享的是一個(gè)使用python實(shí)現(xiàn)的批量檢測(cè)web服務(wù)可用性的腳本代碼,主要功能有測(cè)試一組url的可用性(可以包括HTTP狀態(tài)、響應(yīng)時(shí)間等)并統(tǒng)計(jì)出現(xiàn)不可用情況的次數(shù)和頻率等。
    2016-10-10
  • Python讀取大型數(shù)據(jù)文件的6種方式匯總

    Python讀取大型數(shù)據(jù)文件的6種方式匯總

    在 Python 中,我們可以使用多種方法讀取大型數(shù)據(jù)文件,本文主要為大家介紹6個(gè)常用的Python讀取大型數(shù)據(jù)文件的方法,希望對(duì)大家有所幫助
    2023-05-05
  • Python爬蟲(chóng)框架NewSpaper使用詳解

    Python爬蟲(chóng)框架NewSpaper使用詳解

    這篇文章主要為大家介紹了Python爬蟲(chóng)框架NewSpaper使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Python3.10和Python3.9版本之間的差異介紹

    Python3.10和Python3.9版本之間的差異介紹

    大家好,本篇文章主要講的是Python3.10和Python3.9版本之間的差異介紹,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下哦
    2021-12-12
  • pycocotools介紹以及在windows10下的安裝過(guò)程

    pycocotools介紹以及在windows10下的安裝過(guò)程

    這篇文章主要介紹了pycocotools介紹以及在windows10下的安裝過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • python 檢查文件mime類型的方法

    python 檢查文件mime類型的方法

    今天小編就為大家分享一篇python 檢查文件mime類型的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-12-12
  • 使用Python實(shí)現(xiàn)屏幕截圖功能的詳細(xì)教程

    使用Python實(shí)現(xiàn)屏幕截圖功能的詳細(xì)教程

    Python使用ImageGrab截圖主要依賴于Pillow庫(kù)(PIL庫(kù)的一個(gè)分支),該庫(kù)提供了ImageGrab模塊來(lái)實(shí)現(xiàn)屏幕截圖功能,以下是一個(gè)詳細(xì)的截圖教程,需要的朋友可以參考下
    2025-01-01
  • 深入理解pytorch庫(kù)的dockerfile

    深入理解pytorch庫(kù)的dockerfile

    這篇文章主要介紹了pytorch庫(kù)的dockerfile,主要包括dockerfile命令,使用指令的注意點(diǎn)及存在的一些問(wèn)題,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06

最新評(píng)論

通渭县| 洛南县| 合阳县| 闸北区| 安阳市| 吉安市| 新宁县| 潍坊市| 高淳县| 五台县| 外汇| 广灵县| 绩溪县| 宣威市| 旬阳县| 邢台市| 新乐市| 吴堡县| 谷城县| 长海县| 韩城市| 宣恩县| 东阳市| 长治市| 自贡市| 长丰县| 黄陵县| 奉化市| 定兴县| 昌都县| 齐齐哈尔市| 澜沧| 阳山县| 积石山| 景德镇市| 河西区| 邛崃市| 武强县| 长乐市| 泸西县| 怀来县|