Немного о проекте
Мне, лично, давно была интересна тема шифрования информации, однако, каждый раз погрузившись в эту тему, я осознавал насколько это сложно и понял, что лучше начать с чего-то более простого. Я, лично, планирую написать некоторое количество статей на эту тему, в которых я покажу вам различные алгоритмы шифрования и их реализацию в 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, а пока я предлагаю вам написать в комментариях варианты модернизации программы(код или просо предложения и пожелания). Я обязательно учту ваше мнение.
Drakosh
В какую букву преобразует этот код букву Э при смещении 5? Вопрос именно про реализацию.
Stern_Joe Автор
В данном коде вероятнее всего будет выведен Index Error, так как данный алгоритм не рассчитан на шаг в 5 едениц.
Прошу заметить:
Данный код и его разбор направлены на совсем начинающих программистов или даже школьников.Статья с отладкой, взломом и прочими модернизациями будет опубликована позже. Она будет рассчитана на уже более продвинутых программистов. В данный момент я хотел бы узнать какие модификации хотят видеть читатели.
Спасибо за вопрос.
unsignedchar
Но разве программа не должна учитывать очевидные вещи? Абзац про модульную арифметику был бы понятен и школьникам.
Stern_Joe Автор
Я согласен с Вами. Некоторые моменты могут быть не проработаны, однако у меня есть несколько вариантов решения, которые я хочу подробно рассмотреть и объяснить, как они работают и применяются. Это обыденно дело в моей практике. Сначала дать возможность найти баг, а потом объяснить как он решается.
unsignedchar
"Сначала дать возможность найти баг, а потом объяснить как он решается."
Error-driven development!
makon
del