Перейти к содержимому

Как зашифровать текст на питоне

  • автор:

Шифрование сообщений в Python. От простого к сложному. Шифр Цезаря

Мне, лично, давно была интересна тема шифрования информации, однако, каждый раз погрузившись в эту тему, я осознавал насколько это сложно и понял, что лучше начать с чего-то более простого. Я, лично, планирую написать некоторое количество статей на эту тему, в которых я покажу вам различные алгоритмы шифрования и их реализацию в Python, продемонстрирую и разберу свой проект, созданный в этом направлении. Итак, начнем.

Для начала, я бы хотел рассказать вам какие уже известные алгоритмы мы рассмотрим, в моих статьях. Список вам представлен ниже:

  • Шифр Цезаря
  • Шифр Виженера
  • Шифр замены
  • Омофонический шифр
  • RSA шифрование

Шифр Цезаря

Итак, после небольшого введения в цикл, я предлагаю все-таки перейти к основной теме сегодняшней статьи, а именно к Шифру Цезаря.

Что это такое?

Шифр Цезаря — это простой тип подстановочного шифра, где каждая буква обычного текста заменяется буквой с фиксированным числом позиций вниз по алфавиту. Принцип его действия можно увидеть в следующей иллюстрации:

Какими особенностями он обладает?

У Шифра Цезаря, как у алгоритма шифрования, я могу выделить две основные особенности. Первая особенность — это простота и доступность метода шифрования, который, возможно поможет вам погрузится в эту тему, вторая особенность — это, собственно говоря, сам метод шифрования.

Программная реализация

В интернете существует огромное множество уроков, связанных с криптографией в питоне, однако, я написал максимально простой и интуитивно понятный код, структуру которого я вам продемонстрирую.

Начнем, пожалуй, с создания алфавита. Для этого вы можете скопировать приведенную ниже строку или написать все руками.

alfavit = 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ' # Создаем алфавит

Далее, нам нужно обозначить программе шаг, то есть смещение при шифровании. Так, например, если мы напишем букву «а» в сообщении, тот при шаге «2», программа выведет нам букву «в».

Итак, создаем переменную smeshenie, которая будет вручную задаваться пользователем, и message, куда будет помещаться наше сообщение, и, с помощью метода upper(), возводим все символы в нашем сообщении в верхний регистр, чтобы у нас не было ошибок. Потом создаем просто пустую переменную itog, куда мы буем выводить зашифрованное сообщение. Для этого пишем следующее:

smeshenie = int(input('Шаг шифровки: ')) #Создаем переменную с шагом шифровки message = input("Сообщение для шифровки: ").upper() #создаем переменнную, куда запишем наше сообщение itog = '' #создаем переменную для вывода итогового сообщения

Итак, теперь переходим к самому алгоритму шифровки. Первым делом создаем цикл for , где мы определим место букв, задействованных в сообщении, в нашем списке alfavit, после чего определяем их новые места (далее я постараюсь насытить код с пояснениями):

for i in message: mesto = alfavit.find(i) #Вычисляем места символов в списке new_mesto = mesto + smeshenie #Сдвигаем символы на указанный в переменной smeshenie шаг

Далее, мы создаем внутри нашего цикла условие if , в нем мы записываем в список itog мы записываем наше сообщение уже в зашифрованном виде и выводим его:

for i in message: mesto = alfavit.find(i) new_mesto = mesto + smeshenie if i in alfavit: itog += alfavit[new_mesto] # Задаем значения в итог else: itog += i print (itog) 

Модернизация

Вот мы и написали программу, однако она имеет очень большой недостаток: «При использовании последних букв(русских), программа выведет вам английские буквы. Давайте это исправим.

Для начала создадим переменную lang, в которой будем задавать язык нашего шифра, а так же разделим английский и русский алфавиты.

alfavit_EU = 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ' alfavit_RU = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ' smeshenie = int(input('Шаг шифровки: ')) message = input("Сообщение для шифровки: ").upper() itog = '' lang = input('Выберите язык RU/EU: ') #Добавляем возможность выбора языка

Теперь нам надо создать условие, которое проверит выбранный язык и применит его, то есть обратится к нужному нам алфавиту. Для этого пишем само условие и добавляем алгоритм шифрования, с помощью которого будет выполнено шифрование:

if lang == 'RU': for i in message: mesto = alfavit_RU.find(i) # Алгоритм для шифрования сообщения на русском new_mesto = mesto + smeshenie if i in alfavit_RU: itog += alfavit_RU[new_mesto] else: itog += i else: for i in message: mesto = alfavit_EU.find(i) # Алгоритм для шифрования сообщения на английском new_mesto = mesto + smeshenie if i in alfavit_EU: itog += alfavit_EU[new_mesto] else: itog += i 
Дешифровка сообщения

Возможно это прозвучит несколько смешно, но мы смогли только зашифровать сообщение, а насчет его дешифровки мы особо не задумывались, но теперь дело дошло и до неё.

По сути, дешифровка — это алгоритм обратный шифровке. Давайте немного переделаем наш код (итоговый вид вы можете увидеть выше).

Для начала, я предлагаю сделать «косметическую» часть нашей переделки. Для этого перемещаемся в самое начало кода:

alfavit = 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ' smeshenie = int(input('Шаг шифровки: ')) message = input("Сообщение для ДЕшифровки: ").upper() #заменяем слово шифровка, на дешифровка itog = ''

Остальное можно оставить так же, но если у вас есть желание, то можете поменять названия переменных.

По большому счету, самые ‘большие’ изменения у нас произойдут в той части кода, где у нас находится алгоритм, где нам нужно просто поменять знак «+» на знак «-«. Итак, переходим к самому циклу:

if lang == 'RU': for i in message: mesto = alfavit_RU.find(i) new_mesto = mesto + smeshenie # Меняем знак + на знак - if i in alfavit_RU: itog += alfavit_RU[new_mesto] else: itog += i else: for i in message: mesto = alfavit_EU.find(i) # Меняем знак + на знак - new_mesto = mesto + smeshenie if i in alfavit_EU: itog += alfavit_EU[new_mesto] else: itog += i

Итоговый вид программы

Итак, вот мы и написали простейшую программу для шифрования методом Цезаря. Ниже я размещу общий вид программы без моих комментариев, чтобы вы еще раз смогли сравнить свою программу с моей:

alfavit_EU = 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ' alfavit_RU = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ' smeshenie = int(input('Шаг шифровки: ')) message = input("Сообщение для ДЕшифровки: ").upper() itog = '' lang = input('Выберите язык RU/EU: ') if lang == 'RU': for i in message: mesto = alfavit_RU.find(i) new_mesto = mesto + smeshenie if i in alfavit_RU: itog += alfavit_RU[new_mesto] else: itog += i else: for i in message: mesto = alfavit_EU.find(i) new_mesto = mesto + smeshenie if i in alfavit_EU: itog += alfavit_EU[new_mesto] else: itog += i print (itog) 

Итог

Вы успешно написали алгоритм шифровки и дешифровки сообщения на Python с помощью метода Цезаря. В следующей статье мы с вами рассмотрим Шифр Виженера, а также разберем его реализацию на Python, а пока я предлагаю вам написать в комментариях варианты модернизации программы(код или просо предложения и пожелания). Я обязательно учту ваше мнение.

  • Python
  • Программирование

Задача на питоне. Зашифровать текст

Напишите программу, которая «зашифровывает» текст, хранящийся в переменной proverb, меняя местами символы, стоящие на нечётных и чётных позициях. Результат шифрования нужно вывести на экран с помощью функции print

Используйте переменную proverb для хранения исходной фразы и переменную new_proverb для хранения «зашифрованной» фразы.

Пример: после шифровки начало фразы должно выглядеть так: рПгоарммсиыт

Вот нужно зашифровать. Как это сделать, используя срез по индексам с указанием шага. По сути нужно создать цикл который перебирает и складывает нужные знаки в определенном порядке
proverb = ‘Программисты — это устройства, преобразующие кофеин в код.’

Голосование за лучший ответ
Берёшь переменную суёшь в 4 строку, закрываешь end.
Молот ШотландцевВысший разум (300933) 3 года назад
В Python нет никакого end

Алексей ХвостовскийМудрец (18112) 3 года назад
new_proverb = ».join([proverb[i+1] + proverb[i] for i in range(0, len(proverb), 2)])

Молот Шотландцев Высший разум (300933) Всё может быть. Генераторы списков в Питоне я пока еще не изучал, а в Джаваскрипте (который знаю гораздо лучше) их нет. Пока решаю всё так как это решалось бы в Джаваскрипте

port portИскусственный Интеллект (181509) 3 года назад

«Принципиальный игнор возможностей Пайтона детектед!» :))))

proverb=list(‘1234567890’)
for i in range(0, len(proverb)-1, 2): proverb[i],proverb[i+1]=proverb[i+1],proverb[i]
print (».join(proverb))

Вместо занудной траханины с «промежуточной» переменной temp для обмена значениями двух переменных, в Пайтоне есть гениальная конструкция:

Шифрование с помощью DES Python

Криптография — это один из главных инструментов обеспечения безопасности. В предыдущей статье я рассказывал про шифрование в Python с помощью библиотек Cryptography и PyCryptodome. Сегодня поговорим про блочный шифр DES.

Шифрование с помощью DES Python

DES — это блочный шифр это означает, что текст для шифрования должен быть кратным восьми, поэтому вам нужно добавить пробелы в конце текста, который вы хотите зашифровать, чтобы получить восемь символов. Работа шифровального API происходит следующим образом:

Сначала создается экземпляр объекта шифра, вызвав функцию new ( ) из соответствующего модуля шифрования с использованием следующего синтаксиса: Crypto . Cipher . DES . new ( ) . Первый параметр — это криптографический ключ, и его длина зависит от используемого шифра. Вы можете передать дополнительные параметры, специфичные для шифра или режима работы.

Для шифрования данных вызовите метод encrypt ( ) объекта шифра с текстом. Метод возвращает зашифрованный фрагмент текста.

Для дешифрования данных вызовите метод decrypt ( ) объекта шифра с шифротекстом. Метод возвращает фрагмент обычного текста.

Следующий сценарий шифрует и имя пользователя, и сообщение, симулирует прием учетных данных сервером, а затем отображает расшифрованные данные:

Лабораторная работа №1. Алгоритмы шифрования

Так как это ваша первая лабораторная работа, то в ней описаны общие требования предъявляемые к выполнению текущей и всех последующих работ.

Каждое задание оценивается в отдельности, таким образом, оценку вы получаете по совокупности выполненных заданий (в лабораторной работе №1 таких заданий — три). В оценку включается балл за стиль выполнения задания, поэтому прочитайте официальное руководство по стилю https://www.python.org/dev/peps/pep-0008/ (также некоторые пояснения по оформлению кода можно найти здесь). Соответствие вашей работы PEP8 можно узнать «прогнав» исходный код вашей программы через утилиту pep8 .

Все исходники к работам вы можете найти в репозитории курса (следите за его обновлениями). Чтобы получить список всех работ достаточно выполнить следующую команду:

$ git clone https://[email protected]/Dementiy/cs102_2016.git 

Описание работы с командой git читай в разделе «Настройка рабочего окружения».

Все дальнейшие изменения в репозитории можно получать с помощью команды git pull (её рекомендуется использовать каждый раз, когда вы приступаете к выполнению новой лабораторной работы):

$ git pull 

Прежде чем приступить к выполнению работы

Перед тем как начать выполнять лабораторную работу не забудьте перейти в рабочую директорию и активировать ваше виртуальное окружение:

$ cd путь/к/рабочей_директории $ workon cs102 

Также создадим ветку разработки (подробнее про git workflow можно прочитать тут):

(cs102) $ git checkout -b develop master Switched to a new branch 'develop' 

Теперь создадим ветку новой функциональности:

(cs102) $ git checkout -b feature/caesar develop Switched to a new branch 'feature/caesar' 

И, наконец, создадим папку, в которой будем хранить все файлы, относящиеся к первой лабораторной работе:

(cs102) $ mkdir homework01 

Шифр Цезаря

Шифр Цезаря является одним из самых простых методов шифрования. Для кодирования сообщения все буквы алфавита сдвигают на три символа вперед:

A -> D, B -> E, C -> F, и так далее 

Сдвиг трёх последних букв алфавита:

X -> A, Y -> B, Z -> C 

Используя шифр Цезаря, слово PYTHON будет закодировано следующим образом:

PYTHON |||||| SBWKRQ 

Вам необходимо написать тело для следующих двух функций:

def encrypt_caesar(plaintext): """ >>> encrypt_caesar("PYTHON") 'SBWKRQ' >>> encrypt_caesar("python") 'sbwkrq' >>> encrypt_caesar("Python3.6") 'Sbwkrq3.6' >>> encrypt_caesar("") '' """ # PUT YOUR CODE HERE return ciphertext def decrypt_caesar(ciphertext): """ >>> decrypt_caesar("SBWKRQ") 'PYTHON' >>> decrypt_caesar("sbwkrq") 'python' >>> decrypt_caesar("Sbwkrq3.6") 'Python3.6' >>> decrypt_caesar("") '' """ # PUT YOUR CODE HERE return plaintext 

В результате переменные ciphertext и plaintext должны содержать зашифрованное и расшифрованное сообщения соответственно.

Подсказка: Воспользуйтесь встроенными функциями ord() и chr(). Функция ord() позволяет получить код указанного символа, например:
>>> ord('A')
65
Функция chr() работает наоборот — возвращает символ по его коду:
>>> chr(65)
'A'

О кодировках можно почитать тут и тут.

В папке homework01 создайте файл с именем caesar.py и шаблоном приведенным выше. Сделайте коммит с первоначальным шаблоном:

(cs102) $ git add homework01/caesar.py (cs102) $ git commit -m "Добавлен шаблон для шифра Цезаря" 

По завершении работы над каждой функцией не забудьте также сделать коммит, например:

(cs102) $ git commit -am "Реализована функция encrypt_caesar()" 
(cs102) $ git commit -am "Реализована функция decrypt_caesar()" 

Проверить работу функций можно с помощью примеров, приведенных в доктестах (текст внутри функции, который заключен в тройные кавычки и похож на работу с интерпретатором в интерактивном режиме). Запустить доктесты можно с помощью следующей команды (при условии, что файл с программой называется caesar.py ):

$ python3 -m doctest -v caesar.py 

Если все тесты были пройдены успешно, то объедините (merge) ваши изменения с веткой develop :

(cs102) $ git checkout develop (cs102) $ git merge --no-ff feature/caesar 

Замечание: Вы можете воспользоваться приложением Source Tree для наглядного отслеживания вносимых изменений.

Практика: Измените ваши функции так, чтобы размер сдвига был произвольным:
encrypt_caesar(plaintext, shift)
decrypt_caesar(plaintext, shift)

Шифр Виженера

Шифр Виженера очень похож на шифр Цезаря, за тем исключением, что каждый символ сообщения сдвигается на определяемое ключом значение. Ключ — это слово, каждый символ которого указывает на сколько позиций должен быть сдвинут соответствующий символ в шифруемом сообщении. Так, A означает сдвиг на 0 символов, B на 1 и т.д.

Если длина ключа меньше длины слова, подлежащего шифрованию, то ключ повторяется необходимое число раз, например:

Простой текст: ATTACKATDAWN Ключ: LEMONLEMONLE Зашифрованный текст: LXFOPVEFRNHR 

Ваша задача написать тело для следующих двух функций так, чтобы переменные ciphertext и plaintext содержали зашифрованное и расшифрованное сообщения соответственно.

def encrypt_vigenere(plaintext, keyword): """ >>> encrypt_vigenere("PYTHON", "A") 'PYTHON' >>> encrypt_vigenere("python", "a") 'python' >>> encrypt_vigenere("ATTACKATDAWN", "LEMON") 'LXFOPVEFRNHR' """ # PUT YOUR CODE HERE return ciphertext def decrypt_vigenere(ciphertext, keyword): """ >>> decrypt_vigenere("PYTHON", "A") 'PYTHON' >>> decrypt_vigenere("python", "a") 'python' >>> decrypt_vigenere("LXFOPVEFRNHR", "LEMON") 'ATTACKATDAWN' """ # PUT YOUR CODE HERE return plaintext 

Обратите внимание, что символы A и a в ключе не оказывают никакого влияния на шифруемое сообщение. Если же в качестве ключа мы будем использовать C или c, то получим шифр Цезаря.

Перед выполнением задания не забудьте создать новую ветвь функциональности feature/vigenere и сделать коммит с шаблоном (файл с шаблоном должен быть размещен в каталоге homework01 под именем vigener.py ):

(cs102) $ git checkout -b feature/vigener develop (cs102) $ git add homework01/vigener.py (cs102) $ git commit -m "Добавлен шаблон для шифра Виженера" 

По окончании работы над каждой функцией не забудьте сделать соответствующие коммиты, как в примере с шифром Цезаря, а также объединенить изменения с веткой develop :

(cs102) $ git checkout develop (cs102) $ git merge --no-ff feature/vigener 

RSA шифрование

Одним из современных методов шифрования является алгоритм шифрования RSA, названный так по первым буквам фамилий его авторов.

Мы не будем здесь вдаваться в подробности работы этого алгоритма (хотя и рассмотрим техническую часть), но следующего объяснения должно быть достаточно для понимания принципов шифрования с открытым ключом:

Show your kid a padlock. This is a kind of lock that locks when you click it (i.e it doesn’t require a key) but requires the key to open the lock.

So, I can send these padlocks to all my friends who want to communicate with me. I will send them only the lock but will keep the key with me.

My friends can write me messages, put it in a box, lock it with my padlock (by clicking it) and send it to me, even over high risk networks. If the box is intercepted, it’s contents will not be compromised since I still have the key with me.

When the box reaches me, I can open my padlock with my key and read the contents. This way, I can send padlocks (public keys) to people outside which they can use to lock boxes (encrypt messages) without being in danger of the contents being compromised as the padlock key (the private key) is always with me and never exchanged over the network.

Работу алгоритма можно разбить на три шага:

  1. Генерация ключей
  2. Шифрование
  3. Расшифровка

От вас в этом задании требуется выполнить только шаг генерации ключей, остальные два шага уже даны (см. исходники к работе).

На этапе генерации создаётся два ключа: открытый (public key, с помощью которого каждый сможет зашифровать сообщение и отправить его нам) и закрытый (private key, которым мы можем расшифровать полученные сообщения). Для этого выбирается два простых числа p и q . Позволим пользователю вводить эти числа, но их необходимо проверять на простоту. Для этого напишем функцию, но предварительно создадим новую ветку функциональности и сделаем коммит с шаблоном для этого задания:

(cs102) $ git checkout -b feature/rsa develop (cs102) $ git add homework01/rsa.py (cs102) $ git commit -m "Добавлен шаблон для RSA шифрования" 

Теперь можно начать работать над функцией is_prime(n) :

def is_prime(n): """ >>> is_prime(2) True >>> is_prime(11) True >>> is_prime(8) False """ # PUT YOUR CODE HERE pass 

Если вы не понимаете, как работают функции, то напишите небольшую программу выводящую True или False в зависимости от того, является число простым или нет. Затем полученный код скопируйте в приведенную выше функцию (вместо ключевого слова pass ) и замените print(True) на return True , а print(False) на return False .

Если вы закончили работу над функцией is_prime(n) — сделайте коммит:

(cs102) $ git commit -am "Реализована функция is_prime(n)" 

После того как были выбраны два простых числа находится их произведение n = p * q (по ходу объяснения заменяйте комментарий со словами PUT YOUR CODE HERE в приведенной ниже функции на соответствующее решение).

def generate_keypair(p, q): if not (is_prime(p) and is_prime(q)): raise ValueError('Both numbers must be prime.') elif p == q: raise ValueError('p and q cannot be equal') # n = pq # PUT YOUR CODE HERE # phi = (p-1)(q-1) # PUT YOUR CODE HERE # Choose an integer e such that e and phi(n) are coprime e = random.randrange(1, phi) # Use Euclid's Algorithm to verify that e and phi(n) are comprime g = gcd(e, phi) while g != 1: e = random.randrange(1, phi) g = gcd(e, phi) # Use Extended Euclid's Algorithm to generate the private key d = multiplicative_inverse(e, phi) # Return public and private keypair # Public key is (e, n) and private key is (d, n) return ((e, n), (d, n)) 

Затем вычисляется функция Эйлера по формуе phi=(p-1)(q-1) .

Далее выбирается число e , отвечающее следующим критериям:

Определить, являются ли числа взаимно простыми можно с помощью алгоритма Евклида. Для этого необходимо вычислить наибольший общий делитель (НОД) и проверить, равен ли он единице. На этом этапе вашей задачей является реализация данного алгоритма:

def gcd(a, b): """ >>> gcd(12, 15) 3 >>> gcd(3, 7) 1 """ # PUT YOUR CODE HERE pass 

Не забудьте закоммитить реализацию функции gcd(a, b) :

(cs102) $ git commit -am "Реализована функция поиска НОД" 

Заключительным этапом на шаге генерации ключей является вычисление d такого что d * e mod phi = 1 . Для его вычисления используется расширенный (обобщенный) алгоритм Евклида (см. стр. 23 этого учебного пособия с подробными объяснениями).

def multiplicative_inverse(e, phi): """ >>> multiplicative_inverse(7, 40) 23 """ # PUT YOUR CODE HERE pass 

Таким образом, полученные пары (e,n) и (d,n) являются открытым и закрытым ключами соответственно.

Снова закоммитьте изменения:

(cs102) git commit -am "Реализованы функции multiplicative_inverse() и generate_keypair()" 

Не забудьте сделать коммит для объединения изменений с веткой develop :

(cs102) $ git checkout develop (cs102) $ git merge --no-ff feature/rsa 

После выполнения всех заданий

После выполнения всех задач лабораторной работы создайте новый релиз:

(cs102) $ git checkout -b release-1.0 develop (cs102) $ git commit -m "Релиз 1.0" 

Если ваша работа была зачтена, то закройте ветвь релиза:

(cs102) $ git checkout master (cs102) $ git merge --no-ff release-1.0 (cs102) $ git tag -a 1.0 

Соответствующие ветви функциональности можно удалить, например:

(cs102) $ git branch -d feature/caesar 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *