Прошу помощи. Имеется задача: https://stepik.org/lesson/Caesar-cipher-23896/step/1?adaptive=true. » , где вместо многоточия внутри кавычек записана зашифрованная последовательность.
Sample Input 1: 3 i am caesar Sample Output 1: Result: «lcdpcfdhvdu»
Итак, вот как я ее решил:
a = int(input()) b = input() c = ‘ abcdefghijklmnopqrstuvwxyz’ res = [] len_c=len(c) for i in b: res.append(c[(c.find(i)+a)%len_c]) print(‘Result: ‘, ‘»‘,».join(res),'»‘, sep = »)
Интерпретатор выводит все верно. На сайте тест не проходит. Подскажите, пожалуйста, где ошибся.
Отслеживать
33k 2 2 золотых знака 29 29 серебряных знаков 59 59 бронзовых знаков
задан 23 ноя 2016 в 0:38
Emil Aliyev Emil Aliyev
129 1 1 золотой знак 6 6 серебряных знаков 13 13 бронзовых знаков
Видимо тесты хитрые.
Правда делать заковыристый тест без какого-либо намёка на то, где ошибка — извращение ИМХО.
– user207618
23 ноя 2016 в 0:52
если честно, эти тесты отвратительные. Уже ДАЛЕКО не в первый раз с подобным сталкиваюсь. Приходится читать все коментарии, часто там кто-то догадывается, где именно проблема с тестами и подсказывает, что нужно сделать. Но в данном случае подсказок не нашел.
Как Зашифровать и Расшифровать Текст на C++ (Криптография)
23 ноя 2016 в 0:56
связанный вопрос: Caesar Cipher issue
23 ноя 2016 в 1:27
b=b.strip() не хватает.
23 ноя 2016 в 1:29
сначала я хотел тоже написать функцию, но потом, как видите, я даже эту чертову строку примитивно написал. Мне кажется, что либо смещение где-то происходит неверно, либо проблема со строкой вывода.
Источник: ru.stackoverflow.com
Шифр Вернама на JavaScript
Вчера мы показали вам невзламываемый шифр Вернама. Теперь напишем собственную реализацию этого шифра на JavaScript.
Принцип работы шифра Вернама
- Нам нужно исходное сообщение и ключ шифрования. Ключ должен быть таким же по размеру, как исходное сообщение, или больше.
- Каждый бит исходного сообщения сопоставляется с битом ключа шифрования. Производится специальная операция XOR, которая отвечает за кодирование
- На выходе получается зашифрованный текст, расшифровать который можно только имея под рукой секретный ключ.
Алгоритм
Сделаем классическую реализацию шифра Вернама:
- Спрашиваем текст исходного сообщения и ключ.
- Если ключ короче сообщения — говорим об этом и сразу генерируем новый ключ нужной длины.
- Шифруем сообщение и выводим результат в консоль.
Единственное отличие нашего алгоритма от классического — принудительная проверка длины ключа. Чтобы шифр нельзя было взломать, ключ должен быть как минимум той же длины, что и исходное сообщение.
Подготовка
Заведём нужные переменные:
// переменные для исходного сообщения, зашифрованного и ключа шифрования var input, output,key; // служебные переменные для шифра var inp, k;
Ещё нам понадобится функция, которая возвращает случайное число в указанном диапазоне. Её мы будем использовать для создания нового ключа, если ключ пользователя будет слишком короткий.
Принципы шифрования и криптографии. Расшифруйте послание!
// генератор случайных чисел в заданном диапазоне function getRandomInt(min, max)
Последнее, что нам осталось сделать, — запросить у пользователя сообщение, которое будем шифровать, и ключ:
// запрашиваем текст, который будем шифровать input = prompt(«Введите исходный текст»); // запрашиваем ключ шифрования key = prompt(«Введите ключ»);
Проверяем ключ
Теперь, когда у нас есть сообщение и ключ, проверим, хватит ли длины ключа или нет. Если не хватит — выведем сообщение и сгенерируем новый ключ.
Обратите внимание на второй параметр в функции, которая возвращает случайное значение. В нашем примере мы взяли число 66535, потому что в первом регистре кодировки Unicode 66536 символов — от 0 до 66535, а JavaScript возвращает коды символов строки как раз в Unicode. Попробуйте поставить число поменьше, например 9999, и посмотрите, как меняются символы в ключе и в готовой шифровке.
Само генерирование ключа очень простое: мы берём случайное число, переводим его в строку функцией String.fromCharCode() и добавляем результат к строке с ключом.
// если длина ключа меньше длины сообщения — говорим пользователю и генерируем свой ключ if ((key.length) < (input.length)) < alert(«Ключ короче сообщения, это небезопасно. Скопируйте новый сгенерированный ключ из консоли браузера.»); // в самом начале ключ будет пустой key = «»; // генерируем новый ключ такой же длины, как и сообщение for (var i = 0; i < input.length; i++) < key += String.fromCharCode(getRandomInt(0,66535)); >// выводим новый ключ шифрования console.log(«Скопируйте новый ключ ↓»); console.log(key); >
Шифруем сообщение
В основе алгоритма Вернама лежит XOR — исключающее ИЛИ. Его особенность в том, что если его применить к зашифрованному тексту снова с тем же ключом, то мы получим расшифрованное исходное сообщение. Это значит, что этим алгоритмом мы можем и шифровать, и расшифровывать.
Логика работы алгоритма такая:
- Берём очередной символ сообщения и ключа.
- Получаем их числовой код.
- Применяем к ним XOR (в JavaScript эта операция обозначается крышечкой: ^) и получаем новое число.
- Это число переводим в символ и прибавляем к строке с зашифрованным текстом.
// шифруем сообщение output = «»; for (i = 0; i < input.length; i++) < // берём цифровое значение очередного символа в сообщении и ключе inp = input.charCodeAt(i); k = key.charCodeAt(i); // и применяем к ним исключающее или — XOR output += String.fromCharCode(inp ^ k); >// выводим результат шифрования console.log(«Результат работы алгоритма ↓»); console.log(output);
Если хотите проверить, как работает алгоритм, расшифруйте это сообщение
вот этим ключом:
Это может показаться удивительным, но в нашем примере длина ключа и сообщения совпадают. Это связано с особенностью кодировки Unicode — один код может одновременно кодировать несколько визуальных символов, поэтому длина кажется разной.
Что дальше
В нашей реализации шифра есть несколько минусов:
- в настоящей криптографии не используют функцию Math.random() в таком явном виде. Есть методы подбора и взлома этой псевдослучайной последовательности, по которой можно восстановить, казалось бы, случайные символы.
- Если мы хотим отправить длинное сообщение, то нам нужно его и ключ копировать и вставлять в поле ввода. Намного проще сделать чтение из файла — и сообщения, и ключа.
- Чтобы пользоваться этим алгоритмом, нужно постоянно передавать ключ, а это — проблема. Намного проще сделать так: сгенерировать очень длинную случайную последовательность и использовать её части при каждом шифровании или расшифровке. А использованные фрагменты сразу удалять, чтобы не снижать стойкость шифра.
- И да, у нас нет в явном виде функции расшифровки
Когда-нибудь мы соберёмся с силами и исправим все три пункта.
// генератор случайных чисел в заданном диапазоне function getRandomInt(min, max) < return Math.floor(Math.random() * (max — min)) + min; >// переменные для исходного сообщения, зашифрованного и ключа шифрования var input, output,key; // служебные переменные для шифра var inp, k; // запрашиваем текст, который будем шифровать input = prompt(«Введите исходный текст»); // запрашиваем ключ шифрования key = prompt(«Введите ключ»); // если длина ключа меньше длины сообщения — говорим пользователю и генерируем свой ключ if ((key.length) < (input.length)) < alert(«Ключ короче сообщения, это небезопасно. Скопируйте новый сгенерированный ключ из консоли браузера.»); // в самом начале ключ будет пустой key = «»; // генерируем новый ключ такой же длины, как и сообщение for (var i = 0; i < input.length; i++) < key += String.fromCharCode(getRandomInt(0,66535)); >// выводим новый ключ шифрования console.log(«Скопируйте новый ключ ↓»); console.log(key); > // шифруем сообщение output = «»; for (i = 0; i < input.length; i++) < // берём цифровое значение очередного символа в сообщении и ключе inp = input.charCodeAt(i); k = key.charCodeAt(i); // и применяем к ним исключающее или — XOR output += String.fromCharCode(inp ^ k); >// выводим результат шифрования console.log(«Результат работы алгоритма ↓»); console.log(output);
Источник: thecode.media
Статья Шифр Цезаря: шифратор/дешифратор с красивым GUI на PySide6
Приветствую друзья!
В данной статье напишем шифратор/дешифратор Цезаря на Python и прикрутим к нему GUI.
По окончанию работ наше приложение будет выглядеть так:
ОС — WIndows 10. Python 3.7+, я использую 3.11.2 (последний на момент написания статьи)
Писать проект будем в PyCharm
Дизайнить интерфейс в QtDesigner
Свяжем интерфейс с нашим python проектом с помощью PySide6
PySide6 — привязка языка Python к инструментарию Qt, совместимая на уровне API с PyQt. PySide6 доступна для свободного использования как в открытых, так и закрытых, в частности, коммерческих проектах, поскольку лицензирована по LGPL.
Итак, установим необходимые инструменты:
Ссылка скрыта от гостей
Ссылка скрыта от гостей
В PyCharm создадим новый проект File -> New Project, я назвал ROT_decoder_GUI
Внутри проекта создадим пару файлов: main.py и cipher_functions.py
Настройки интерпретатора стандартные, переходим в терминал (Alt + F12) и устанавливаем PySide6
pip install pyside6
После установки переходим в директорию ~PycharmProjectsROT_decoder_GUIvenvLibsite-packagesPySide6
Там находятся необходимые бинарники для дальнейшей разработки включая designer.exe
Главное окно программы:
Создадим новую форму Файл -> Новый, выберем Main Window
В инспекторе объектов удаляем menubar и statusbar.
Кидаем на форму объекты Layout — 2 вертикальных и 3 горизонтальных. В дальнейшем на них будем накидывать наши элементы.
Устанавливаем необходимые объекты, в скобочках напишу.
1. Ввод текста для шифрования/дешифрования (label, Text Edit)
2. Вывод расшифрованного/ зашифрованного текста (label, Text Edit)
3. Кнопки (Push Button — 3 штуки)
4. Слайдер и спинбокс (Label, Horizontal Slider и Spin Box)
5. Label об авторе, ссылки, год, копирайт и т.д. (label)
Двойным кликом в инспекторе даем осмысленные имена.
В инспекторе выделяем объект central widget и кнопкой на панели инструментов компонуем все по вертикали.
Приступим к стилизации наших объектов. В инспекторе ПКМ по Main WIndows -> Изменить Style Sheet..
Имеется поддержка CSS, что лично для меня очень удобно, добавляем наш код:
QTextEdit < border: 2px solid gray; border-radius: 5px; >QPushButton < border: 2px solid gray; border-radius: 5px; font: 700 12pt «Hack»; >QPushButton:hover < border-color: #090; >QPushButton:pressed < border: 4px solid #090; border-radius: 5px; >QPushButton:checked < color: white; background-color: #090; border: 2px solid black; border-radius: 5px; >QSlider::sub-page:horizontal < background-color: #090; >QSlider::add-page:horizontal < background-color: gray; >QSlider::handle:horizontal < background-color: black; width: 16px; border-radius:8px; margin-top: -5px; margin-bottom: -5px; >QSlider::groove:horizontal < background-color: transparent; height: 7px; >QLabel < font: 500 11pt «Ubuntu»; >QSpinBox < border: 2px solid gray; border-radius: 5px; background: transparent; padding: 2px; >QSpinBox:hover
Название классов элементов также указано в инспекторе объектов.
В редакторе свойств элементов, уберем у спинбокса кнопки, кнопкам Decrypt и Encrypt (элемент Push Button ) установим свойство Checkable, у Decrypt поставим Checked .
Слайдеру и спинбоксу поставим шаг и значение по умолчанию, у меня 13 (ROT 13)
Осталось разобраться с ресурсами и добавить наши иконки. Я взял иконки из material design от гугла.
С различными свойствами объектов можете поиграться сами (размер, курсор, шрифт и т.д.) Настроек много.
Превью интерфейса смотрим сочетанием Ctrl + R
Проектирование и прототипирование закончено, можно приступить к коду
В файл cipher_functions.py записываем собственно сами функции шифрования/дешифрования по Цезарю.
upper_english_alp = lower_english_alp = upper_russian_alp = lower_russian_alp = def encrypt(original_string: str, shift_key: int) -> str: enc = » for i in original_string: if i.isupper() and i.isalpha() and i in upper_english_alp.values(): enc += upper_english_alp.get(((ord(i) + shift_key — ord(‘A’)) % 26)) elif i.lower() and i.isalpha() and i in lower_english_alp.values(): enc += lower_english_alp.get(((ord(i) + shift_key — ord(‘a’)) % 26)) elif i.isupper() and i.isalpha() and i in upper_russian_alp.values(): enc += upper_russian_alp.get(((ord(i) + shift_key — ord(‘А’)) % 32)) elif i.lower() and i.isalpha() and i in lower_russian_alp.values(): enc += lower_russian_alp.get(((ord(i) + shift_key — ord(‘а’)) % 32)) else: enc += i return enc def decrypt(encrypted_string: str, shift_key: int) -> tuple[str, int, int]: dec = » ru = 0 en = 0 for i in encrypted_string: if i.isupper() and i.isalpha() and i in upper_english_alp.values(): dec += upper_english_alp.get(((ord(i) — shift_key — ord(‘A’)) % 26)) en += 1 elif i.lower() and i.isalpha() and i in lower_english_alp.values(): dec += lower_english_alp.get(((ord(i) — shift_key — ord(‘a’)) % 26)) en += 1 elif i.isupper() and i.isalpha() and i in upper_russian_alp.values(): dec += upper_russian_alp.get(((ord(i) — shift_key — ord(‘А’)) % 32)) ru += 1 elif i.lower() and i.isalpha() and i in lower_russian_alp.values(): dec += lower_russian_alp.get(((ord(i) — shift_key — ord(‘а’)) % 32)) ru += 1 else: dec += i return dec, ru, en
Расскажу вкратце:
С помощью генератора словарей создаем 4 словаря (2 для английского и 2 для русского алфавитов, lower и upper case)
Ключами выступают числа от 0 до длина алфавита, а значениями сами буквы алфавита.
Сами функции отличаются только тем, что при шифровании мы прибавляем шаг(ROT key) и при расшифровке отнимаем.
Функция encrypt возвращает строку -> str, а decrypt кортеж -> tuple[str, int, int]
В decrypt я считаю количество символов русского и английского алфавитов, потом использую это в функции bruteforce.
Ищем остаток от деления для англ алфавита 26, для нашего 32!, как оказалось в юникоде Ё идет НЕ после Е
Можно докрутить, словарь сделать с Ё или заменять ее на Е. В данный момент это не принципиально.
Проводим некоторые проверки if i.isupper() and i.isalpha() and i in upper_english_alp.values()
Регистр, буква ли это и принадлежность к алфавиту. Сделано для того чтобы приложение не трогало цифры, спец. символы, пробелы и т.д.
Теперь нам надо связать интерфейс с приложением.
Каркас приложения — main.py :
import sys from cipher_functions import decrypt, encrypt from PySide6.QtWidgets import QApplication, QMainWindow, QMessageBox from design import Ui_MainWindow class RotDecoder(QMainWindow): def __init__(self): super(RotDecoder, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) if __name__ == «__main__»: app = QApplication(sys.argv) window = RotDecoder() window.show() sys.exit(app.exec())
Есть пару вариантов превратить наш design.ui в design.py
1. Из Qt designer — Форма -> Показать код Python, далее копируем или сохраняем в design.py
2. В PyCharm Alt + F12 pyside6-uic .design.ui -o .design.py
Ресурсы — pyside6-rcc .resources.qrc -o resources.py
Ресурсы линкуются в файле design.py, проверяем правильность импорта: import resources
Свяжем spinbox и slider по изменению значений, создадим функцию в классе RotDecoder файла main.py :
def connection_slider_spinbox(self) -> None: self.ui.horizontalSlider.valueChanged.connect(self.ui.spinBox.setValue) self.ui.spinBox.valueChanged.connect(self.ui.horizontalSlider.setValue)
Прописываем метод в конструкторе класса:
class RotDecoder(QMainWindow): def __init__(self): . . . self.connection_slider_spinbox()
Добавим наш функционал:
def decrypting(self): self.ui.textEdit_2.setText(decrypt(self.ui.textEdit.toPlainText(), self.ui.spinBox.value())[0]) def encrypting(self): self.ui.textEdit_2.setText(encrypt(self.ui.textEdit.toPlainText(), self.ui.spinBox.value()))
Берем текст из textEdit и помещает его в textEdit_2
Кнопки Decrypt и Encrypt не могут быть в одинаковом состоянии(checked), меняем при нажатии:
def checked_dec_btn(self): self.ui.decrypt_btn.nextCheckState() self.encrypting() self.ui.spinBox.valueChanged.connect(self.encrypting) self.ui.textEdit.textChanged.connect(self.encrypting) def checked_enc_btn(self): self.ui.encrypt_btn.nextCheckState() self.decrypting() self.ui.spinBox.valueChanged.connect(self.decrypting) self.ui.textEdit.textChanged.connect(self.decrypting)
Кнопка BRUTEFORCE :
def bruteforce(self): self.ui.textEdit_2.clear() if decrypt(self.ui.textEdit.toPlainText(), 1)[1] > decrypt(self.ui.textEdit.toPlainText(), 1)[2]: for i in range(1, 33): ls = [‘ROT key ‘ + str(i) + ‘: ‘ + decrypt(self.ui.textEdit.toPlainText(), i)[0] + ‘n’ for i in range(1, 33)] with open(‘bruted.txt’, ‘w’, encoding=’UTF-8′) as file: file.writelines(ls) self.ui.textEdit_2.append(f’ROT key :’) else: for i in range(1, 27): ls = [‘ROT key ‘ + str(i) + ‘: ‘ + decrypt(self.ui.textEdit.toPlainText(), i)[0] + ‘n’ for i in range(1, 27)] with open(‘bruted.txt’, ‘w’, encoding=’UTF-8′) as file: file.writelines(ls) self.ui.textEdit_2.append(f’ROT key : ‘)
Брутфорс выводит и записывает в файл bruted.txt все возможные комбинации от 1 до конца алфавита.
Заполняем класс нашими методами:
class RotDecoder(QMainWindow): def __init__(self): super(RotDecoder, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.connection_slider_spinbox() self.decrypting() self.ui.spinBox.valueChanged.connect(self.decrypting) self.ui.textEdit.textChanged.connect(self.decrypting) self.ui.encrypt_btn.clicked.connect(self.checked_dec_btn) self.ui.decrypt_btn.clicked.connect(self.checked_enc_btn) self.ui.brute_btn.clicked.connect(self.bruteforce) self.ui.actionExit.triggered.connect(sys.exit) self.ui.actionabout.triggered.connect(self.about)
Сборка приложения под Windows:
Осталось превратить наш проект в исполняемый файл. Компиляцию можно делать разными способами, например PyInstaller или Nuitka.
Я выбрал второе, устанавливаем Nuitka:
pip install nuitka
Чтобы собрать все приложение в один единственный исполняемый EXE файл на понадобится библиотека zstandart:
pip install zstandard
nuitka —onefile —follow-imports —enable-plugin=pyside6 —windows-disable-console —windows-icon-from-ico=reskey.ico —remove-output -o caesar_cipher.exe main.py
—onefile — собираем в 1 файл
—follow-imports — соблюдаем импорты
—enable-plugin=pyside6 — добавляем плагин PySide6
—windows-disable-console — убираем консольное окно
—windows-icon-from-ico=reskey.ico — ставим иконку из файла
—remove-output — после удаляем все папки генерируемые во время компиляции
Кстати говоря наше приложение получилось кроссплатформенным и при желание его можно собрать под MacOS или Linux!
Прикладываю файлы проекта и скомпилированный исходник. Вот так вот «просто» можно собрать GUI для приложения на Python!
Ссылка скрыта от гостей
Если что-то забыл указать, спрашивайте! Отвечу, исправлю.
За сием прощаюсь, до новых встреч!
Источник: codeby.net