1
0
Преглед на файлове

Загрузить файлы 'ОАиП/2024-25/36гр\Подвербный\'

u22-26podverbny преди 2 седмици
родител
ревизия
cd1b532857
променени са 1 файла, в които са добавени 230 реда и са изтрити 0 реда
  1. 230 0
      ОАиП/2024-25/36гр/Подвербный/Новый вижинер с анимацией.py

+ 230 - 0
ОАиП/2024-25/36гр/Подвербный/Новый вижинер с анимацией.py

@@ -0,0 +1,230 @@
+import sqlite3
+import tkinter as tk
+from tkinter import ttk
+import time
+
+# Создание таблицы для заполнения
+conn = sqlite3.connect("vigenere.db")
+cursor = conn.cursor()
+cursor.execute("""
+CREATE TABLE IF NOT EXISTS alphabets (
+    id INTEGER PRIMARY KEY AUTOINCREMENT,
+    name TEXT UNIQUE,
+    alphabet TEXT
+)
+""")
+conn.commit()
+
+# Запись алфавита
+cursor.execute("SELECT COUNT(*) FROM alphabets")
+if cursor.fetchone()[0] == 0:
+    cursor.execute("INSERT INTO alphabets (name, alphabet) VALUES (?, ?)",
+                   ("Русский (с Ё)", "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"))
+    cursor.execute("INSERT INTO alphabets (name, alphabet) VALUES (?, ?)",
+                   ("Русский (без Ё)", "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"))
+    cursor.execute("INSERT INTO alphabets (name, alphabet) VALUES (?, ?)",
+                   ("Русский (с подчеркиванием)", "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"))
+    conn.commit()
+
+# Глобальная переменная для заполения алфавита выбранного
+alphabet = ""
+
+# Цветовая функция
+def get_color_for_key(letter):
+    colors = ["red", "blue", "green", "orange", "purple", "magenta", "cyan", "brown"]
+    return colors[ord(letter) % len(colors)]
+
+def build_table_lines():
+    cell_width = 3
+    # Выравнивание по првому краю
+    header = " " * cell_width + "".join([letter.rjust(cell_width) for letter in alphabet])
+    
+    raw_key = key_entry.get().upper()
+    unique_key = ""
+    for ch in raw_key:
+        if ch in alphabet and ch not in unique_key:
+            unique_key += ch
+
+    rows = []
+    for letter in unique_key:
+        shift = alphabet.index(letter) + 1
+        rotated = alphabet[shift:] + alphabet[:shift]
+        row = letter.rjust(cell_width) + "".join([r.rjust(cell_width) for r in rotated])
+        rows.append(row)
+        
+    return [header] + rows, unique_key
+
+def update_table():
+    lines, _ = build_table_lines()
+    full_text = "\n".join(lines)
+    table_display.config(state="normal")
+    table_display.delete("1.0", "end")
+    table_display.insert("1.0", full_text)
+    table_display.config(state="disabled")
+
+def update_table_in_text(content):
+    table_display.config(state="normal")
+    table_display.delete("1.0", "end")
+    table_display.insert("1.0", content)
+    table_display.config(state="disabled")
+
+def animate_intersection(key_letter, plaintext_letter, ciphertext_letter):
+  
+    # Анимация сканирования и движения для выбранной буквы ключа
+   
+    cell_width = 3
+    lines, unique_key = build_table_lines()
+    if key_letter not in unique_key:
+        return
+    row_index = unique_key.index(key_letter) + 1
+    
+    shift = alphabet.index(key_letter) + 1
+    rotated = alphabet[shift:] + alphabet[:shift]
+    try:      
+        target_col = rotated.index(ciphertext_letter)
+    except ValueError:
+        target_col = 0
+
+    # Пробег по таблице
+    for j in range(len(alphabet)):
+        new_lines = list(lines)
+        row = new_lines[row_index]
+        cells = [row[i:i+cell_width] for i in range(0, len(row), cell_width)]
+        if j < len(cells) - 1:
+            cells[j+1] = "(" + rotated[j].strip() + ")"
+        new_lines[row_index] = key_letter.rjust(cell_width) + "".join(cells[1:])
+        update_table_in_text("\n".join(new_lines))
+        table_display.update()
+        time.sleep(0.2)
+        if j == target_col:
+            perform_upward_animation(key_letter, target_col, rotated,
+                                     row_index, cell_width, lines)
+            break
+
+def perform_upward_animation(key_letter, target_col, rotated, row_index, cell_width, base_lines):
+    
+    #Анимация подъёма найденной ячейки.
+    
+    floating_frames = 4
+    for frame in range(floating_frames):
+        new_lines = list(base_lines)
+        new_row_index = row_index - (frame + 1)
+        if new_row_index < 1:
+            new_row_index = 1
+        # Обновляем строку с буквой ключа
+        orig_line = new_lines[row_index]
+        cells = [orig_line[i:i+cell_width] for i in range(0, len(orig_line), cell_width)]
+        cells[target_col+1] = rotated[target_col].rjust(cell_width)
+        new_lines[row_index] = key_letter.rjust(cell_width) + "".join(cells[1:])
+        
+        # Обновляем строку куда перемещаеться 
+        float_line = new_lines[new_row_index]
+        float_cells = [float_line[i:i+cell_width] for i in range(0, len(float_line), cell_width)]
+        if target_col+1 < len(float_cells):
+            float_cells[target_col+1] = rotated[target_col].center(cell_width)
+        else:
+            float_cells.append(rotated[target_col].center(cell_width))
+        new_lines[new_row_index] = "".join(float_cells)
+        
+        update_table_in_text("\n".join(new_lines))
+        table_display.config(state="normal")
+        line_num = new_row_index + 1
+        start_col = (target_col+1) * cell_width
+        end_col = start_col + cell_width
+        table_display.tag_remove("highlight", "1.0", "end")
+        table_display.tag_add("highlight", f"{line_num}.{start_col}", f"{line_num}.{end_col}")
+        # Выбор цвета
+        table_display.tag_config("highlight", foreground=get_color_for_key(key_letter))
+        table_display.config(state="disabled")
+        table_display.update()
+        time.sleep(0.3)
+    time.sleep(0.5)
+    update_table()
+
+def vigenere_cipher(text, decrypt=False):
+   
+    text = text.upper()
+    key = key_entry.get().upper()
+    if not key:
+        return text
+    result = ""
+    for i, char in enumerate(text):
+        if char in alphabet:
+            current_key = key[i % len(key)]
+            shift = alphabet.index(current_key)
+            if decrypt:
+                new_index = (alphabet.index(char) - shift) % len(alphabet)
+            else:
+                new_index = (alphabet.index(char) + shift) % len(alphabet)
+            output_letter = alphabet[new_index]
+            if decrypt:
+                animate_intersection(current_key, output_letter, char)
+            else:
+                animate_intersection(current_key, char, output_letter)
+            result += output_letter
+        else:
+            result += char
+    return result
+
+def encrypt():
+    update_table()
+    encrypted_text = vigenere_cipher(input_text.get(), decrypt=False)
+    output_text.config(text=encrypted_text)
+
+def decrypt():
+    update_table()
+    decrypted_text = vigenere_cipher(input_text.get(), decrypt=True)
+    output_text.config(text=decrypted_text)
+
+def load_alphabet(event=None):
+    global alphabet
+    selected = alphabet_var.get()
+    cursor.execute("SELECT alphabet FROM alphabets WHERE name = ?", (selected,))
+    result = cursor.fetchone()
+    if result:
+        alphabet = result[0]
+        # Вариант с подчеркиванием
+        if selected == "Русский (с подчеркиванием)" and not alphabet.endswith("_"):
+            alphabet += "_"
+        update_table()
+
+# Интерфейс 
+root = tk.Tk()
+root.title("Шифр Виженера")
+root.geometry("800x600")
+
+alphabet_var = tk.StringVar()
+ttk.Label(root, text="Выберите алфавит").pack()
+cursor.execute("SELECT name FROM alphabets")
+alphabet_options = [row[0] for row in cursor.fetchall()]
+alphabet_menu = ttk.Combobox(root, textvariable=alphabet_var, values=alphabet_options, state="readonly")
+alphabet_menu.pack()
+alphabet_menu.bind("<<ComboboxSelected>>", load_alphabet)
+
+ttk.Label(root, text="Введите ключ").pack()
+key_entry = tk.Entry(root)
+key_entry.pack()
+key_entry.bind("<KeyRelease>", lambda event: update_table())
+
+table_display = tk.Text(root, font=("Courier", 14), bd=0, highlightthickness=0, wrap="none")
+table_display.pack(pady=10, fill="x")
+table_display.tag_config("highlight", foreground="red")
+table_display.config(state="disabled")
+
+ttk.Label(root, text="Введите текст").pack()
+input_text = tk.Entry(root)
+input_text.pack(pady=5)
+
+buttons_frame = tk.Frame(root)
+buttons_frame.pack(pady=10)
+encrypt_button = tk.Button(buttons_frame, text="Зашифровать", command=encrypt)
+encrypt_button.pack(side=tk.LEFT, padx=10)
+decrypt_button = tk.Button(buttons_frame, text="Дешифровать", command=decrypt)
+decrypt_button.pack(side=tk.RIGHT, padx=10)
+
+ttk.Label(root, text="Результат:").pack()
+output_text = tk.Label(root, text="", fg="red", font=("Courier", 14))
+output_text.pack(pady=10)
+
+root.mainloop()
+conn.close()