Загрузка данных


# -*- coding: utf-8 -*-
import tkinter as tk
from tkinter import scrolledtext, messagebox

class CaesarEncryptorApp:
    def __init__(self, root):
        self.root = root
        self.root.title("Шифратор / Дешифратор (Лабораторная)")
        self.root.geometry("620x520")
        self.root.resizable(False, False)

        # Алфавит: кириллица (стр+загл), латиница (стр+загл), цифры, пробел и базовая пунктуация
        self.alphabet = (
            "абвгдеёжзийклмнопрстуфхцчшщъыьэюя"
            "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"
            "abcdefghijklmnopqrstuvwxyz"
            "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
            "0123456789 .,!?-_"
        )

        self._setup_ui()

    def _setup_ui(self):
        # Исходный текст
        tk.Label(self.root, text="Исходный текст:", font=("Arial", 10)).pack(anchor="w", padx=15, pady=(10, 2))
        self.input_txt = scrolledtext.ScrolledText(self.root, height=7, width=75, font=("Consolas", 10))
        self.input_txt.pack(padx=15, pady=2)

        # Ключ и режим
        ctrl_frame = tk.Frame(self.root)
        ctrl_frame.pack(fill="x", padx=15, pady=8)

        tk.Label(ctrl_frame, text="Ключ (сдвиг):", font=("Arial", 10)).pack(side="left", padx=(0, 5))
        self.key_var = tk.StringVar(value="5")
        tk.Entry(ctrl_frame, textvariable=self.key_var, width=6, font=("Arial", 10)).pack(side="left", padx=5)

        tk.Label(ctrl_frame, text="Режим:", font=("Arial", 10)).pack(side="left", padx=(15, 5))
        self.mode_var = tk.StringVar(value="encrypt")
        tk.Radiobutton(ctrl_frame, text="Шифрование", variable=self.mode_var, value="encrypt", font=("Arial", 10)).pack(side="left")
        tk.Radiobutton(ctrl_frame, text="Дешифрование", variable=self.mode_var, value="decrypt", font=("Arial", 10)).pack(side="left")

        # Кнопки
        btn_frame = tk.Frame(self.root)
        btn_frame.pack(pady=8)
        tk.Button(btn_frame, text="Обработать", command=self._process, width=12, bg="#4CAF50", fg="white", font=("Arial", 10)).pack(side="left", padx=10)
        tk.Button(btn_frame, text="Очистить", command=self._clear, width=12, bg="#f44336", fg="white", font=("Arial", 10)).pack(side="left", padx=10)

        # Результат
        tk.Label(self.root, text="Результат:", font=("Arial", 10)).pack(anchor="w", padx=15, pady=(2, 2))
        self.output_txt = scrolledtext.ScrolledText(self.root, height=7, width=75, state="disabled", font=("Consolas", 10))
        self.output_txt.pack(padx=15, pady=2)

    def _shift_char(self, char, shift):
        if char in self.alphabet:
            idx = self.alphabet.index(char)
            # В Python оператор % корректно работает с отрицательными числами
            new_idx = (idx + shift) % len(self.alphabet)
            return self.alphabet[new_idx]
        return char  # символы вне алфавита остаются без изменений

    def _process(self):
        try:
            key = int(self.key_var.get())
        except ValueError:
            messagebox.showerror("Ошибка ввода", "Ключ должен быть целым числом.")
            return

        text = self.input_txt.get("1.0", tk.END).strip()
        if not text:
            messagebox.showwarning("Внимание", "Введите текст для обработки.")
            return

        mode = self.mode_var.get()
        shift = key if mode == "encrypt" else -key
        shift = shift % len(self.alphabet)

        result = "".join(self._shift_char(ch, shift) for ch in text)

        self.output_txt.config(state="normal")
        self.output_txt.delete("1.0", tk.END)
        self.output_txt.insert(tk.END, result)
        self.output_txt.config(state="disabled")

    def _clear(self):
        self.input_txt.delete("1.0", tk.END)
        self.key_var.set("5")
        self.output_txt.config(state="normal")
        self.output_txt.delete("1.0", tk.END)
        self.output_txt.config(state="disabled")


if __name__ == "__main__":
    root = tk.Tk()
    app = CaesarEncryptorApp(root)
    root.mainloop()