Rurecoder: различия между версиями

Материал из ALT Linux Wiki
Строка 56: Строка 56:
         self.undo_stack = []
         self.undo_stack = []
         self.redo_stack = []
         self.redo_stack = []
        # Горячие клавиши
         self.bind("<Control-z>", self.undo)
         self.bind("<Control-z>", self.undo)
         self.bind("<Control-y>", self.redo)
         self.bind("<Control-y>", self.redo)
         self.bind("<Control-Shift-Z>", self.redo)
         self.bind("<Control-Shift-Z>", self.redo)
         self.bind("<Key>", self.add_to_undo_stack)
         self.bind("<Key>", self.add_to_undo_stack)
        # Контекстное меню
        self.context_menu = tk.Menu(self, tearoff=0)
        self.context_menu.add_command(label="Вырезать (Ctrl+X)", command=self.cut_text)
        self.context_menu.add_command(label="Копировать (Ctrl+C)", command=self.copy_text)
        self.context_menu.add_command(label="Вставить (Ctrl+V)", command=self.paste_text)
        self.context_menu.add_command(label="Удалить (Del)", command=self.delete_text)
        self.context_menu.add_separator()
        self.context_menu.add_command(label="Выделить все (Ctrl+A)", command=self.select_all)
        self.context_menu.add_separator()
        self.context_menu.add_command(label="Отменить (Ctrl+Z)", command=self.undo)
        self.context_menu.add_command(label="Повторить (Ctrl+Y)", command=self.redo)
        self.bind("<Button-3>", self.show_context_menu)  # Правая кнопка мыши
        self.bind("<Button-1>", self.hide_context_menu)  # Левая кнопка мыши


     def add_to_undo_stack(self, event):
     def add_to_undo_stack(self, event):
Строка 86: Строка 103:
         self.delete("1.0", tk.END)
         self.delete("1.0", tk.END)
         self.insert("1.0", text[:-1])  # Удаляем последний \n
         self.insert("1.0", text[:-1])  # Удаляем последний \n
    def show_context_menu(self, event):
        try:
            self.context_menu.tk_popup(event.x_root, event.y_root)
        finally:
            self.context_menu.grab_release()
    def hide_context_menu(self, event):
        self.context_menu.unpost()
    def cut_text(self):
        self.event_generate("<<Cut>>")
    def copy_text(self):
        self.event_generate("<<Copy>>")
    def paste_text(self):
        self.event_generate("<<Paste>>")
    def delete_text(self):
        self.event_generate("<Delete>")
    def select_all(self):
        self.tag_add(tk.SEL, "1.0", tk.END)
        self.mark_set(tk.INSERT, "1.0")
        self.see(tk.INSERT)
        return "break"


def process_paragraph(paragraph):
def process_paragraph(paragraph):
Строка 112: Строка 156:
         output = process_paragraph(paragraph)
         output = process_paragraph(paragraph)


        # Формируем результат в зависимости от настроек
         if add_numbers_var.get():
         if add_numbers_var.get():
             result_text = f"Абзац {idx}:\n{output}"
             result_text = f"Абзац {idx}:\n{output}"
Строка 118: Строка 161:
             result_text = output
             result_text = output


        # Добавляем переносы строк в зависимости от настроек
         if remove_empty_lines_var.get():
         if remove_empty_lines_var.get():
             output_textbox.insert(tk.END, f"{result_text}\n")
             output_textbox.insert(tk.END, f"{result_text}\n")
Строка 125: Строка 167:


     output_textbox.see(tk.END)
     output_textbox.see(tk.END)
def handle_paste(event):
    try:
        selected = event.widget.tag_ranges(tk.SEL)
        if selected:
            event.widget.delete(tk.SEL_FIRST, tk.SEL_LAST)
        event.widget.insert(tk.INSERT, event.widget.clipboard_get())
        return "break"
    except tk.TclError:
        pass
def handle_cut(event):
    if event.widget.tag_ranges(tk.SEL):
        event.widget.clipboard_clear()
        event.widget.clipboard_append(event.widget.get(tk.SEL_FIRST, tk.SEL_LAST))
        event.widget.delete(tk.SEL_FIRST, tk.SEL_LAST)
        return "break"
def handle_delete(event):
    if event.widget.tag_ranges(tk.SEL):
        event.widget.delete(tk.SEL_FIRST, tk.SEL_LAST)
        return "break"
def handle_select_all(event):
    event.widget.tag_add(tk.SEL, "1.0", tk.END)
    event.widget.mark_set(tk.INSERT, "1.0")
    event.widget.see(tk.INSERT)
    return "break"


def open_github(event):
def open_github(event):
     webbrowser.open("https://github.com/Text-extend-tools/python-rurecoder")
     webbrowser.open("https://github.com/Text-extend-tools/python-rurecoder")


# Создаем главное окно
root = tk.Tk()
root = tk.Tk()
root.title("Rurecoder GUI")
root.title("Rurecoder GUI")
Строка 194: Строка 209:
warning_label.pack(pady=(0, 5))
warning_label.pack(pady=(0, 5))


# Используем наш кастомный класс с поддержкой undo/redo
# Поле ввода с поддержкой undo/redo и контекстным меню
input_textbox = TextWithUndo(input_frame, wrap=tk.WORD, font=("Arial", 12))
input_textbox = TextWithUndo(input_frame, wrap=tk.WORD, font=("Arial", 12))
input_textbox.pack(fill=tk.BOTH, expand=True)
input_textbox.pack(fill=tk.BOTH, expand=True)


# Выходное поле (тоже с поддержкой undo/redo)
# Выходное поле
output_frame = ttk.LabelFrame(text_frame, text="Результат")
output_frame = ttk.LabelFrame(text_frame, text="Результат")
output_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5)
output_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5)
Строка 204: Строка 219:
output_textbox = TextWithUndo(output_frame, wrap=tk.WORD, font=("Arial", 12), state=tk.NORMAL)
output_textbox = TextWithUndo(output_frame, wrap=tk.WORD, font=("Arial", 12), state=tk.NORMAL)
output_textbox.pack(fill=tk.BOTH, expand=True)
output_textbox.pack(fill=tk.BOTH, expand=True)
# Привязка обработчиков
input_textbox.bind("<<Paste>>", handle_paste)
input_textbox.bind("<Control-x>", handle_cut)
input_textbox.bind("<Delete>", handle_delete)
input_textbox.bind("<Control-a>", handle_select_all)
output_textbox.bind("<<Paste>>", handle_paste)
output_textbox.bind("<Control-x>", handle_cut)
output_textbox.bind("<Delete>", handle_delete)
output_textbox.bind("<Control-a>", handle_select_all)


# Фрейм для кнопки
# Фрейм для кнопки
Строка 231: Строка 235:
info_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
info_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)


info_text = """Rurecoder GUI - написана Ахламовым Петром с помощью ChatGPT и DeepSeek. 2025 г.
info_text = """Rurecoder GUI - написана Ахламовым Петром с помощью ChatGPT и DeepSeek.


Используется Rurecoder от zvezdochiot.
Используется Rurecoder от zvezdochiot.


Каждая строчка обрабатывается как отдельный абзац.
- Каждая строчка обрабатывается как отдельный абзац.
В одном абзаце может быть только один вид кодировки.
- В одном абзаце может быть только один вид кодировки.
"""
"""


Строка 278: Строка 282:
link_label.pack(pady=(0, 20))
link_label.pack(pady=(0, 20))
link_label.bind("<Button-1>", open_github)
link_label.bind("<Button-1>", open_github)
# Обработчик клика по пустому месту в главном окне
def hide_menus(event):
    input_textbox.context_menu.unpost()
    output_textbox.context_menu.unpost()
root.bind("<Button-1>", hide_menus)


root.mainloop()
root.mainloop()

Версия от 10:36, 14 июня 2025

< Soft

Rurecoder
Разработчик(и) zvezdochiot
Первый выпуск ~2018
Лицензия PDM 1.0
Сайт github.com

Rurecoder - программа для дешифровки текста, на подобие Windows-программы Штирлиц.

Установка

$ git clone https://github.com/zvezdochiot/python-rurecoder #(based https://bitbucket.org/dkuryakin/recoder.git)
# cd python-rurecoder
# cp -r rurecoder /usr/lib64/python3/site-packages

Использование

Примечание: Чтобы расшифровать текст, скопируйте кракозябры в чистый текстовый файл и сохраните его в UTF-8

В консоли

$ echo "Îñíîâíàÿ Îëèìïèéñêàÿ äåðåâíÿ â" | python3 -m rurecoder
Основная Олимпийская деревня в

Декодировка файла с выводом

$ cat '/home/user/enca.txt'
Ëþäè â Ãðîóâëåíäå, ìàëåíüêîì (ïî ìåðêàì Êàëèôîðíèè) ãîðîäêå â øåñòüñîò æèòåëåé, âûõîäèëè íà óëèöû, ñòîÿëè ïåðåä ñâîèìè äîìàìè ñ öâåòàìè íà ïîäîêîííèêàõ è ñìîòðåëè, êàê ýòîò ïèðîêóìóëþñ âûðàñòàåò âûøå Ñüåððû-Íåâàäû. ß è ñàìà ñòîÿëà òàì â áëàãîãîâåíèè è óæàñå è ïîíèìàëà áåç âñÿêèõ ñëîâ, ÷òî åñëè íå ïîéäåò äîæäü, òî ñëåäóþùèå ïîæàðû áóäóò åù¸ óæàñíåå, à åñëè äîæäè âñ¸ æå ïîéäóò è îêàæóòñÿ ñëèøêîì îáèëüíûìè, òî ýòî ñîææ¸ííûå ãîðíûå ñêëîíû ñìîåò íàâîäíåíèÿìè. Âñ¸ áûëî áóêâàëüíî íà ãðàíè êàòàñòðîôû. Íî ðÿäîì áûëè öâåòû â ãîðøêàõ, è íåîáîææ¸ííûå ñîñíû, è òðóùèåñÿ î íîãè ñîáàêè, è ðåñòîðàí, îòêðûòûé äëÿ óæèíà; è ÷óâñòâîâàëîñü, ÷òî âñå íà óëèöå âçäûõàþò ñ áëàãîäàðíîñòüþ çà òî, ÷òî âñ¸ ýòî ó íèõ åù¸ åñòü. Õîòÿ áû íåíàäîëãî (Äèàíà Ìàðêóì, Äåñÿòûé îñòðîâ).
$ cat '/home/user/enca.txt' | python3 -m rurecoder
Люди в Гроувленде, маленьком (по меркам Калифорнии) городке в шестьсот жителей, выходили на улицы, стояли перед своими домами с цветами на подоконниках и смотрели, как этот пирокумулюс вырастает выше Сьерры-Невады. Я и сама стояла там в благоговении и ужасе и понимала без всяких слов, что если не пойдет дождь, то следующие пожары будут ещё ужаснее, а если дожди всё же пойдут и окажутся слишком обильными, то это сожжённые горные склоны смоет наводнениями. Всё было буквально на грани катастрофы. Но рядом были цветы в горшках, и необожжённые сосны, и трущиеся о ноги собаки, и ресторан, открытый для ужина; и чувствовалось, что все на улице вздыхают с благодарностью за то, что всё это у них ещё есть. Хотя бы ненадолго (Диана Маркум, Десятый остров).

Декодировка в новый файл

$ cat '/home/user/enca.txt' | python3 -m rurecoder > /home/user/decom.txt

GUI

Создайте файл с расширением .py со следующим содержимым и запустите его командой python3 file.py


Rurecoder-gui.png

Инструкция

  • Из-за Pyttk обработка текста выполняется горячими клавишами

Дополнительно

Примеры кракозябр для теста

Исходная кодировка При декодировании воспринято как Результат Распознает
При воспроизведении применяется та же кодировка, что и при создании текста. Широкая электрификация южных губерний даст мощный толчок подъёму сельского хозяйства.
Windows-1251 Windows-1252 или
ISO 8859-1
Øèðîêàÿ ýëåêòðèôèêàöèÿ þæíûõ ãóáåðíèé äàñò ìîùíûé òîë÷îê ïîäú¸ìó ñåëüñêîãî õîçÿéñòâà.
KOI8-R ьХПНЙЮЪ ЩКЕЙРПХТХЙЮЖХЪ ЧФМШУ ЦСАЕПМХИ ДЮЯР ЛНЫМШИ РНКВНЙ ОНДЗ╦ЛС ЯЕКЭЯЙНЦН УНГЪИЯРБЮ.
ISO 8859-5 иш№юърџ §ыхъђ№шєшърішџ ўцэћѕ уѓсх№эшщ фрёђ ьюљэћщ ђюыїюъ яюфњИьѓ ёхыќёъюую ѕючџщёђтр.
CP 866 ╪шЁюър ¤ыхъЄЁшЇшърЎш ■цэ√ї уєсхЁэшщ фрёЄ ью∙э√щ Єюыўюъ яюф·╕ьє ёхы№ёъюую їюч щёЄтр. Теряет "я"
КОИ-8|KOI8-R Windows-1252 или
ISO 8859-1
ûÉÒÏËÁÑ ÜÌÅËÔÒÉÆÉËÁÃÉÑ ÀÖÎÙÈ ÇÕÂÅÒÎÉÊ ÄÁÓÔ ÍÏÝÎÙÊ ÔÏÌÞÏË ÐÏÄߣÍÕ ÓÅÌØÓËÏÇÏ ÈÏÚÑÊÓÔ×Á.
Windows-1251 ыЙТПЛБС ЬМЕЛФТЙЖЙЛБГЙС АЦОЩИ ЗХВЕТОЙК ДБУФ НПЭОЩК ФПМЮПЛ РПДЯЈНХ УЕМШУЛПЗП ИПЪСКУФЧБ.
ISO 8859-5 ћЩвЯЫСб мЬХЫдвЩЦЩЫСУЩб РжЮйШ ЧеТХвЮЩЪ ФСгд ЭЯнЮйЪ дЯЬоЯЫ аЯФпЃЭе гХЬигЫЯЧЯ ШЯкбЪгдзС.
CP 866 √╔╥╧╦┴╤ ▄╠┼╦╘╥╔╞╔╦┴├╔╤ └╓╬┘╚ ╟╒┬┼╥╬╔╩ ─┴╙╘ ═╧▌╬┘╩ ╘╧╠▐╧╦ ╨╧─▀г═╒ ╙┼╠╪╙╦╧╟╧ ╚╧┌╤╩╙╘╫┴.
7 бит {IROKAQ \LEKTRIFIKACIQ @VNYH GUBERNIJ DAST MO]NYJ TOL^OK POD_#MU SELXSKOGO HOZQJSTWA. не распознает
ISO 8859-5 Windows-1252 или
ISO 8859-1
ÈØàÞÚÐï íÛÕÚâàØäØÚÐæØï îÖÝëå ÓãÑÕàÝØÙ ÔÐáâ ÜÞéÝëÙ âÞÛçÞÚ ßÞÔêñÜã áÕÛìáÚÞÓÞ åÞ×ïÙáâÒÐ.
Windows-1251 ИШаЮЪРп нЫХЪваШдШЪРжШп оЦЭле УгСХаЭШЩ ФРбв ЬЮйЭлЩ вЮЫзЮЪ ЯЮФксЬг бХЫмбЪЮУЮ еЮЧпЩбвТР.
КОИ-8/KOI8-R хьЮчзпО МшузБЮьДьзпФьО НжщКЕ сЦяуЮщьы тпАБ эчИщКы БчшГчз ъчтЙЯэЦ АушЛАзчсч ЕчвОыАБрп.
Альтернативная кодировка/CP 866 ╚╪р▐┌╨я э█╒┌тр╪ф╪┌╨ц╪я ю╓▌ых ╙у╤╒р▌╪┘ ╘╨ст ▄▐щ▌ы┘ т▐█ч▐┌ ▀▐╘ъё▄у с╒█ьс┌▐╙▐ х▐╫я┘ст╥╨.
Альтернативная кодировка|CP 866 Windows-1252 ˜¨à®ª ï í«¥ªâà¨ä¨ª æ¨ï ëå £ã¡¥à­¨© ¤ áâ ¬®é­ë© ⮫箪 ¯®¤êñ¬ã ᥫì᪮£® å®§ï©á⢠. Не распознал ш, а, .
Windows-1251 �Ёа®Є п н«ҐЄваЁдЁЄ жЁп о¦­ле ЈгЎҐа­Ё© ¤ бв ¬®й­л© в®«з®Є Ї®¤кс¬г ᥫмбЄ®Ј® е®§п©бвў . Не распознал ш, а
КОИ-8 ≤╗Ю╝╙═О М╚╔╙БЮ╗Д╗╙═Ф╗О Н╕╜КЕ ёЦ║╔Ю╜╗╘ ╓═АБ ╛╝И╜К╘ Б╝╚Г╝╙ ╞╝╓ЙЯ╛Ц А╔╚ЛА╙╝ё╝ Е╝╖О╘АБ╒═.
ISO 8859-5 �ЈрЎЊ я эЋЅЊтрЈфЈЊ цЈя юІ­ых ЃуЁЅр­ЈЉ Є ст ЌЎщ­ыЉ тЎЋчЎЊ ЏЎЄъёЌу сЅЋьсЊЎЃЎ хЎЇяЉстЂ . Не распознал ш, а, .
CP437 ÿ¿α«¬á∩ φ½Ñ¬Γα¿Σ¿¬áµ¿∩ δσ úπíÑα¡¿⌐ ñáßΓ ¼«Θ¡δ⌐ Γ«½τ«¬ »«ñΩ±¼π ßѽ∞߬«ú« σ«º∩⌐ßΓóá. Не распознал
UTF-8 Windows-1252 Широкая электрификация южных губерний даст мощный толчок подъёму сельского хозяйства. Не распознал а, э, с
Windows-1251 Широкая электрификация южных губерний даст мощный толчок подъёму сельского хозяйства.
КОИ-8 п╗п╦я─п╬п╨п╟я▐ я█п╩п╣п╨я┌я─п╦я└п╦п╨п╟я├п╦я▐ я▌п╤п╫я▀я┘ пЁя┐п╠п╣я─п╫п╦п╧ п╢п╟я│я┌ п╪п╬я┴п╫я▀п╧ я┌п╬п╩я┤п╬п╨ п©п╬п╢я┼я▒п╪я┐ я│п╣п╩я▄я│п╨п╬пЁп╬ я┘п╬п╥я▐п╧я│я┌п╡п╟.
ISO 8859-5 аЈаИб�аОаКаАб� б�аЛаЕаКб�б�аИб�аИаКаАб�аИб� б�аЖаНб�б� аГб�аБаЕб�аНаИаЙ аДаАб�б� аМаОб�аНб�аЙ б�аОаЛб�аОаК аПаОаДб�б�аМб� б�аЕаЛб�б�аКаОаГаО б�аОаЗб�аЙб�б�аВаА. Криво распознал
CP 866 ╨и╨╕╤А╨╛╨║╨░╤П ╤Н╨╗╨╡╨║╤В╤А╨╕╤Д╨╕╨║╨░╤Ж╨╕╤П ╤О╨╢╨╜╤Л╤Е ╨│╤Г╨▒╨╡╤А╨╜╨╕╨╣ ╨┤╨░╤Б╤В ╨╝╨╛╤Й╨╜╤Л╨╣ ╤В╨╛╨╗╤З╨╛╨║ ╨┐╨╛╨┤╤К╤С╨╝╤Г ╤Б╨╡╨╗╤М╤Б╨║╨╛╨│╨╛ ╤Е╨╛╨╖╤П╨╣╤Б╤В╨▓╨░.
UTF-16 CP 866 (♦8♦@♦>♦:♦0♦O♦ M♦;♦5♦:♦B♦@♦8♦D♦8♦:♦0♦F♦8♦O♦ N♦6♦=♦K♦E♦ 3♦C♦1♦5♦@♦=♦8♦9♦ 4♦0♦A♦B♦ <♦>♦I♦=♦K♦9♦ B♦>♦;♦G♦>♦:♦  ?♦>♦4♦J♦Q♦<♦C♦ A♦5♦;♦L♦A♦:♦>♦3♦>♦ E♦>♦7♦O♦9♦A♦B♦2♦0♦. Криво распознал