-
Notifications
You must be signed in to change notification settings - Fork 0
/
tools.py
98 lines (75 loc) · 3.83 KB
/
tools.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import re
import webbrowser
from tkinter import *
def callback(url):
webbrowser.open_new(url)
def copy_text(containing_widget):
""" Копировать содержимое виджета текстового поля в буфер обмена. """
containing_widget.clipboard_clear() # Очистить буфер обмена
containing_widget.clipboard_append(
containing_widget.get("1.0", END)) # Скопировать текст из Text виджета в буфер обмена
def paste_text(containing_widget):
""" Вставить текст из буфера обмена в виджет текстового поля. """
try:
text = containing_widget.selection_get(selection='CLIPBOARD') # Получить текст из буфера обмена
containing_widget.insert(INSERT, text) # Вставить текст в виджет Text
except TclError:
pass # Обработка ошибки, если буфер обмена пуст или содержимое невозможно получить
def clear_textfield(containing_widget):
""" Очистить содержимое виджета текстового поля. """
containing_widget.delete("1.0", END)
def detect_language(text):
if re.search(r'[А-Я]', text):
language = 'ru'
elif re.search(r'[A-Z]', text):
language = 'en'
else:
raise ValueError("Введите текст на русском или английском.")
return language
def fix_text(text, mode: str):
""" mode - decryption или encryption"""
text = text.upper().replace('Ё', 'Е')
if re.search(r'[\d]', # ^a-zA-Zа-яА-ЯёЁ\s.,!?;:\-–—\'"«»“”
text): # или просто \d, чтобы уведомлять, что в тексте есть цифры
raise ValueError(
"В сообщении не должно быть цифр. Напишите их текстом или очистите сообщение от этих символов.")
if mode == 'hacking':
if re.search(r'[А-Я]', text) and re.search(r'[A-Z]', text):
raise ValueError("Сообщение содержит символы из русского и английского алфавитов. Используйте один алфавит.")
if mode == 'encryption':
text = re.sub(r'[^A-ZА-Я]', '', text)
# text = ' '.join([text[i:i + 5] for i in range(0, len(text), 5)])
return text
def get_frequency(cipher):
cipher_frequencies = {}
total_count = len(cipher)
for char in cipher:
if char in cipher_frequencies:
cipher_frequencies[char] += 1
else:
cipher_frequencies[char] = 1
for char in cipher_frequencies:
cipher_frequencies[char] = (cipher_frequencies[char] / total_count)
return cipher_frequencies
def least_squares(real_frequency, expected_frequency):
return sum(
(real_frequency.get(char, 0) - expected_frequency.get(char, 0)) ** 2 for char in expected_frequency)
def decryption(cipher, alphabet, frequency_table):
# cipher = fix_text(cipher, 'decryption')
best_shift = None
min_error = float('inf')
for shift in range(len(alphabet)):
decrypted_text = ''.join(
alphabet[(alphabet.index(char) - shift) % len(alphabet)] if char in alphabet else char
for char in cipher
)
decrypted_frequency = get_frequency(decrypted_text)
error = least_squares(decrypted_frequency, frequency_table)
if error < min_error:
min_error = error
best_shift = shift
decrypted_text = ''.join(
alphabet[(alphabet.index(char) - best_shift) % len(alphabet)] if char in alphabet else char
for char in cipher
)
return decrypted_text, best_shift