Skip to content

Python Application for Compression files and Encryption

Notifications You must be signed in to change notification settings

meta-syfu/Compression

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Compression & Encryption

A Python Application for Compress and Encrypt files

برنامه فشرده سازی و رمزنگاری فایل ها به زبان پایتون

این پروژه شامل فشرده‌سازی و رمزنگاری فایل‌ها با استفاده از دو الگوریتم مختلف برای فشرده‌سازی (Huffman و zlib) و یک روش رمزنگاری متقارن است.

در این پروژه مدیریت ارور ها در هر بخش بصورت کامل هندل و پیام های مشخصی قرار داده ایم

پیشنیاز ها

برای اجرای این برنامه نیاز به نصب پیش‌نیازها را داریم، در یک فایل requirements.txt لیست کتابخانه‌های مورد نیاز را قرار داده ایم که محتوای این فایل به صورت زیر است:

cryptography
Pillow
ttkthemes
tk

دستور نصب پیش‌نیازها

برای نصب پیش‌نیازها، دستور زیر را در ترمینال یا خط فرمان اجرا کنید:

pip install -r requirements.txt

این دستور تمامی کتابخانه‌های مورد نیاز پروژه را نصب می‌کند.

توضیحات نصب پیش‌نیازها

cryptography:

این کتابخانه برای رمزنگاری و رمزگشایی فایل‌ها استفاده می‌شود. الگوریتم Fernet از این کتابخانه برای انجام عملیات رمزنگاری و رمزگشایی استفاده می‌کند.

Pillow:

این کتابخانه برای کار با تصاویر استفاده می‌شود. در این پروژه برای نمایش لوگو در رابط کاربری گرافیکی از Pillow استفاده شده است.

ttkthemes:

این کتابخانه تم‌های زیباتری برای رابط کاربری tkinter فراهم می‌کند و به بهبود ظاهر برنامه کمک می‌کند.

tk:

این کتابخانه برای ایجاد رابط گرافیکی و نمایش آن استفاده شده است.

اجرای برنامه

پس از نصب پیش‌نیازها، برای اجرای برنامه کافی است فایل gui.py را اجرا کنید. می‌توانید از دستور زیر استفاده کنید:

python gui.py

فشرده‌سازی و باز کردن فشرده‌سازی با استفاده از zlib

فایل compression.py وظیفه فشرده‌سازی و باز کردن فشرده‌سازی فایل‌ها را با استفاده از کتابخانه zlib برعهده دارد.

تابع compress_file

این تابع یک فایل را با استفاده از الگوریتم فشرده‌سازی zlib فشرده می‌کند.

import zlib

def compress_file(input_file, output_file):
    try:
        with open(input_file, 'rb') as f:
            data = f.read()

        compressed_data = zlib.compress(data, level=9)
        with open(output_file, 'wb') as f:
            f.write(compressed_data)
    except Exception as e:
        print(f"Error during zlib compression: {e}")
  • وارد کردن zlib: کتابخانه zlib برای فشرده‌سازی استفاده می‌شود.
  • خواندن فایل ورودی: فایل ورودی به صورت باینری باز و محتویات آن خوانده می‌شود.
  • فشرده‌سازی داده‌ها: داده‌ها با استفاده از zlib.compress و سطح فشرده‌سازی ۹ فشرده می‌شوند.
  • نوشتن فایل خروجی: داده‌های فشرده‌شده در فایل خروجی به صورت باینری نوشته می‌شوند.
  • مدیریت خطا: هرگونه استثنا که در طول فرآیند رخ دهد، گرفته شده و چاپ می‌شود.

تابع decompress_file

این تابع فایل فشرده‌شده با zlib را باز می‌کند.

def decompress_file(input_file, output_file):
    try:
        with open(input_file, 'rb') as f:
            compressed_data = f.read()

        data = zlib.decompress(compressed_data)
        with open(output_file, 'wb') as f:
            f.write(data)
    except Exception as e:
        print(f"Error during zlib decompression: {e}")
  • خواندن فایل فشرده‌شده: فایل ورودی به صورت باینری باز و محتویات فشرده‌شده آن خوانده می‌شود.
  • باز کردن فشرده‌سازی داده‌ها: داده‌ها با استفاده از zlib.decompress باز می‌شوند.
  • نوشتن فایل خروجی: داده‌های باز شده در فایل خروجی به صورت باینری نوشته می‌شوند.
  • مدیریت خطا: هرگونه استثنا که در طول فرآیند رخ دهد، گرفته شده و چاپ می‌شود.

رمزنگاری و رمزگشایی

فایل encryption.py وظیفه رمزنگاری و رمزگشایی فایل‌ها را با استفاده از رمزنگاری متقارن Fernet از کتابخانه cryptography برعهده دارد.

تابع generate_key

یک کلید رمزنگاری جدید تولید و آن را در یک فایل ذخیره می‌کند.

from cryptography.fernet import Fernet

def generate_key():
    key = Fernet.generate_key()
    with open("key.key", "wb") as key_file:
        key_file.write(key)
  • وارد کردن Fernet: از ماژول cryptography.fernet.
  • تولید کلید: یک کلید رمزنگاری جدید با استفاده از Fernet.generate_key تولید می‌شود.
  • ذخیره کلید: کلید تولید‌شده در فایل key.key به صورت باینری نوشته می‌شود.

تابع load_key

این تابع کلید رمزنگاری ذخیره‌شده را بارگذاری می‌کند.

def load_key():
    return open("key.key", "rb").read()
  • بارگذاری کلید: فایل key.key به صورت باینری باز و کلید خوانده می‌شود.

تابع encrypt_file

این تابع یک فایل را با استفاده از کلید داده‌شده رمزنگاری می‌کند.

def encrypt_file(input_file, output_file, key):
    f = Fernet(key)
    with open(input_file, 'rb') as file:
        file_data = file.read()
    encrypted_data = f.encrypt(file_data)
    with open(output_file, 'wb') as file:
        file.write(encrypted_data)
  • ایجاد شیء Fernet: از کلید داده‌شده برای ایجاد یک شیء Fernet استفاده می‌شود.
  • خواندن فایل ورودی: فایل ورودی به صورت باینری باز و داده‌های آن خوانده می‌شوند.
  • رمزنگاری داده‌ها: داده‌های فایل با استفاده از روش Fernet رمزنگاری می‌شوند.
  • نوشتن فایل خروجی: داده‌های رمزنگاری‌شده در فایل خروجی به صورت باینری نوشته می‌شوند.

تابع decrypt_file

این تابع یک فایل رمزنگاری‌شده را با استفاده از کلید داده‌شده رمزگشایی می‌کند.

def decrypt_file(input_file, output_file, key):
    f = Fernet(key)
    with open(input_file, 'rb') as file:
        encrypted_data = file.read()
    decrypted_data = f.decrypt(encrypted_data)
    with open(output_file, 'wb') as file:
        file.write(decrypted_data)
  • ایجاد شیء Fernet: از کلید داده‌شده برای ایجاد یک شیء Fernet استفاده می‌شود.
  • خواندن فایل ورودی: فایل ورودی به صورت باینری باز و داده‌های رمزنگاری‌شده آن خوانده می‌شود.
  • رمزگشایی داده‌ها: داده‌های رمزنگاری‌شده با استفاده از روش Fernet رمزگشایی می‌شوند.
  • نوشتن فایل خروجی: داده‌های رمزگشایی‌شده در فایل خروجی به صورت باینری نوشته می‌شوند.

رابط کاربری گرافیکی (GUI)

فایل gui.py یک رابط کاربری گرافیکی با استفاده از کتابخانه tkinter برای فشرده‌سازی، باز کردن فشرده‌سازی، رمزنگاری و رمزگشایی فایل‌ها ایجاد می‌کند.

کلاس CompressionApp

این کلاس رابط کاربری برنامه را مدیریت می‌کند.

import tkinter as tk
from tkinter import filedialog, messagebox
from ttkthemes import ThemedTk
import huffman
import compression
import encryption
import os
import tarfile
import webbrowser
from PIL import Image, ImageTk

class CompressionApp:
    def __init__(self, root):
        self.root = root
        self.root.title("File Compression and Encryption")
        self.root.geometry("500x450")

        # Load logo image
        self.load_logo()

        self.method_var = tk.StringVar(value="huffman")
        encryption.generate_key()
        self.key = encryption.load_key()

        self.create_widgets()

    def load_logo(self):
        try:
            self.logo_image = Image.open("logo.png")
            self.logo_image = self.logo_image.resize((100, 100), Image.LANCZOS)
            self.logo_photo = ImageTk.PhotoImage(self.logo_image)
        except Exception as e:
            print(f"Error loading logo: {e}")
            self.logo_photo = None

    def create_widgets(self):
        frame = tk.Frame(self.root)
        frame.pack(padx=10, pady=10)

        # Display logo
        if self.logo_photo:
            logo_label = tk.Label(frame, image=self.logo_photo)
            logo_label.grid(row=0, column=0, columnspan=2, pady=10)

        tk.Label(frame, text="Select Compression Method:", font=("Helvetica", 14)).grid(row=1, column=0, columnspan=2, pady=10)
        
        tk.Radiobutton(frame, text="Huffman", variable=self.method_var, value="huffman", font=("Helvetica", 12)).grid(row=2, column=0, sticky="e", padx=5)
        tk.Radiobutton(frame, text="Zlib", variable=self.method_var, value="zlib", font=("Helvetica", 12)).grid(row=2, column=1, sticky="w", padx=5)
        
        tk.Button(frame, text="Import File(s)", command=self.choose_input_files, width=20, font=("Helvetica", 10)).grid(row=3, column=0, columnspan=2, pady=10)
        
        tk.Button(frame, text="Compress", command=self.compress, width=20, font=("Helvetica", 10)).grid(row=4, column=0, pady=5, padx=5)
        tk.Button(frame, text="Encrypt", command=self.encrypt, width=20, font=("Helvetica", 10)).grid(row=4, column=1, pady=5, padx=5)
        
        tk.Button(frame, text="Decompress", command=self.decompress, width=20, font=("Helvetica", 10)).grid(row=5, column=0, pady=5, padx=5)
        tk.Button(frame, text="Decrypt", command=self.decrypt, width=20, font=("Helvetica", 10)).grid(row=5, column=1, pady=5, padx=5)

        # Add GitHub link
        github_label = tk.Label(frame, text="GitHub: meta-syfu", font=("Helvetica", 12), fg="blue", cursor="hand2")
        github_label.grid(row=6, column=0, columnspan=2, pady=20)
        github_label.bind("<Button-1>", lambda e: webbrowser.open("https://github.com/meta-syfu/compression"))

        self.input_files = []
        self.output_file = None

    def choose_input_files(self):
        self.input_files = filedialog.askopenfilenames(title="Select File(s)")
        if not self.input_files:
            messagebox.showwarning("Warning", "No files selected!")
    
    def compress(self):
        if not self.input_files:
            messagebox.showwarning("Warning", "No files selected!")
            return

        for input_file in self.input_files:
            output_file = input_file + ".huff" if self.method_var.get() == "huffman" else input_file + ".zlib"
            try:
                if self.method_var.get() == "huffman":
                    huffman.compress_file(input_file, output_file)
                else:
                    compression.compress_file(input_file, output_file)
                messagebox.showinfo("Success", f"File compressed successfully: {output_file}")
            except Exception as e:
                messagebox.showerror("Error", f"Compression failed: {e}")

    def decompress(self):
        if not self.input_files:
            messagebox.showwarning("Warning", "No files selected!")
            return

        for input_file in self.input_files:
            if input_file.endswith(".huff"):
                output_file = input_file.replace(".huff", "")
                try:
                    huffman.decompress_file(input_file, output_file)
                    messagebox.showinfo("Success", f"File decompressed successfully: {output_file}")
                except Exception as e:
                    messagebox.showerror("Error", f"Decompression failed: {e}")
            elif input_file.endswith(".zlib"):
                output_file = input_file.replace(".zlib", "")
                try:
                    compression.decompress_file(input_file, output_file)
                    messagebox.showinfo("Success", f"File decompressed successfully: {output_file}")
                except Exception as e:
                    messagebox.showerror("Error", f"Decompression failed: {e}")
            else:
                messagebox.showwarning("Warning", "Unsupported file format for decompression!")

    def encrypt(self):
        if not self.input_files:
            messagebox.showwarning("Warning", "No files selected!")
            return

        for input_file in self.input_files:
            output_file = input_file + ".enc"
            try:
                encryption.encrypt_file(input_file, output_file, self.key)
                messagebox.showinfo("Success", f"File encrypted successfully: {output_file}")
            except Exception as e:
                messagebox.showerror("Error", f"Encryption failed: {e}")

    def decrypt(self):
        if not self.input_files:
            messagebox.showwarning("Warning", "No files selected!")
            return

        for input_file in self.input_files:
            if input_file.endswith(".enc"):
                output_file = input_file.replace(".enc", "")
                try:
                    encryption.decrypt_file(input_file, output_file, self.key)
                    messagebox.showinfo("Success", f"File decrypted successfully: {output_file}")
                except Exception as e:
                    messagebox.showerror("Error", f"Decryption failed: {e}")
            else:
                messagebox.showwarning("Warning", "Unsupported file format for decryption!")

    def open_github(self, event):
        webbrowser.open_new("https://github.com/meta-syfu/compression")
  • وارد کردن کتابخانه‌های لازم: کتابخانه‌های مختلفی از جمله tkinter، filedialog، messagebox، ttkthemes، huffman، compression، encryption، os، tarfile، webbrowser، PIL برای ایجاد رابط کاربری گرافیکی و عملیات مختلف فایل وارد می‌شوند.
  • تعریف کلاس CompressionApp: این کلاس تمام عملکردهای رابط کاربری برنامه را مدیریت می‌کند.
  • تابع __init__: این تابع اصلی است که تمام ویجت‌های رابط کاربری را ایجاد و تنظیم می‌کند.
  • تابع load_logo: این تابع لوگوی برنامه را بارگذاری و تنظیم می‌کند.
  • تابع create_widgets: این تابع ویجت‌های مختلف مانند دکمه‌ها، لیبل‌ها و رادیوباتن‌ها را ایجاد می‌کند.
  • تابع choose_input_files: این تابع فایل‌های ورودی را انتخاب می‌کند.
  • تابع compress: این تابع فایل‌های انتخاب‌شده را فشرده می‌کند.
  • تابع decompress: این تابع فایل‌های انتخاب‌شده را باز می‌کند.
  • تابع encrypt: این تابع فایل‌های انتخاب‌شده را رمزنگاری می‌کند.
  • تابع decrypt: این تابع فایل‌های انتخاب‌شده را رمزگشایی می‌کند.
  • تابع open_github: این تابع لینک مخزن GitHub را باز می‌کند.

توضیحات درباره کتابخانه tarfile و استفاده آن در پروژه

کتابخانه tarfile

کتابخانه tarfile یکی از کتابخانه‌های استاندارد پایتون است که برای کار با فایل‌های بایگانی (archive files) با فرمت tar استفاده می‌شود. این کتابخانه به شما اجازه می‌دهد تا فایل‌ها و دایرکتوری‌ها را در یک فایل tar فشرده و یا از آن خارج کنید. فایل‌های tar به طور گسترده‌ای برای انتقال دسته‌ای از فایل‌ها استفاده می‌شوند، مخصوصاً در سیستم‌های مبتنی بر یونیکس.

استفاده از tarfile در این پروژه

در این پروژه، از کتابخانه tarfile برای فشرده‌سازی چندین فایل به یک فایل tar و استخراج فایل‌ها از آن استفاده شده است. این کار به سادگی مدیریت و انتقال فایل‌ها کمک می‌کند.

نمونه‌های کد استفاده از tarfile
  1. فشرده‌سازی فایل‌ها به یک فایل tar

    در تابع compress_files در فایل gui.py، از tarfile برای ایجاد یک فایل tar و افزودن فایل‌های فشرده‌شده به آن استفاده می‌شود:

    def compress_files(self, input_files, output_file, method="huffman"):
        try:
            with tarfile.open(output_file, "w") as tar:
                for input_file in input_files:
                    compressed_file = input_file + ".compressed"
                    if method == "huffman":
                        huffman.compress_file(input_file, compressed_file)
                    elif method == "zlib":
                        compression.compress_file(input_file, compressed_file)
                    tar.add(compressed_file, arcname=os.path.basename(compressed_file))
                    os.remove(compressed_file)
        except Exception as e:
            print(f"Error during compression: {e}")

    در این بخش، فایل‌های ورودی ابتدا فشرده می‌شوند و سپس به فایل tar اضافه می‌گردند. پس از افزودن به فایل tar، فایل‌های فشرده موقت حذف می‌شوند.

  2. استخراج فایل‌ها از یک فایل tar

    در تابع decompress_files در فایل gui.py، از tarfile برای استخراج فایل‌ها از یک فایل tar استفاده می‌شود:

    def decompress_files(self, input_file, output_dir, method="huffman"):
        try:
            with tarfile.open(input_file, "r") as tar:
                tar.extractall(path=output_dir)
                for member in tar.getmembers():
                    compressed_file = os.path.join(output_dir, member.name)
                    decompressed_file = os.path.splitext(compressed_file)[0]
                    if method == "huffman":
                        huffman.decompress_file(compressed_file, decompressed_file)
                    elif method == "zlib":
                        compression.decompress_file(compressed_file, decompressed_file)
                    os.remove(compressed_file)
        except Exception as e:
            print(f"Error during decompression: {e}")

    در این بخش، فایل tar استخراج می‌شود و سپس فایل‌های فشرده‌شده باز می‌شوند. پس از باز کردن فشرده‌سازی، فایل‌های فشرده موقت حذف می‌شوند.

نتیجه‌گیری

این پروژه شامل پیاده‌سازی الگوریتم‌های فشرده‌سازی و رمزنگاری فایل‌ها با استفاده از کتابخانه‌های مختلف پایتون است. رابط کاربری گرافیکی ایجاد شده با استفاده از tkinter به شما اجازه می‌دهد تا به سادگی فایل‌های خود را فشرده‌سازی، باز کردن فایل های فشرده‌سازی شده، رمزنگاری و رمزگشایی کنند.

About

Python Application for Compression files and Encryption

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages