вторник, 22 января 2013 г.

Многоалфавитные шифры (Русский язык) на Python 3.3.0

Добрый день.

Хочу рассказать, а даже скорее оставить для себя заметку, как я писал Многоалфавитный шифр .
Небольшая информационная справка из методички:

       Слабая криптостойкость моноалфавитных подстановок преодолевается с применением подстановок многоалфавитных.    Для защиты от частотного анализа были разработаны многоалфавитные шифры, в которых для шифрования сообщения периодически используется несколько различных подстановочных алфавитов.  Если задано r подстановочных алфавитов, то исходное сообщение разбивается на группы по r символов, для шифрования i-го символа группы используется i-ый подстановочный алфавит. Например, для r=4 буквы с номерами 1,5,9,13, ... шифруются 1 алфавитом, буквы с номерами 2,7,10,14, ... - 2 алфавитом, и т.д.
Для получения открытого текста выделяются повторяющиеся группы знаков, и определяется период повторения. Предполагаемый период проверяется составлением частотного распределения для каждой n-й буквы зашифрованного текста. Если каждое из  n частотных распределений имеет сильную неоднородность, характерную для моноалфавитной подстановки, то предполагаемый период является правильным. Затем задача решается как n различных простых подстановок. 



Исходные данные:
Исходный алфавит Подстановочный алфавит
1 2 3
А Б С М
Б Ю О Н
В Г У О
Г Ы М П
Д У К Р
Е Ь Х С
Ё З Ч Т
Ж Ш И У
Х Й Щ Ф
И  Ц Ж Х
Й Л Ъ Ц
К Ф Д Ч
Л Н Э Ш
М Т В Щ
Н П  Я Ъ
О Р А Ь
П С Б Ы
Р О Ю Э
С У Г Ю
Т М пробел Я
У Х Е пробел
Ф К Ь А
Х Ч З Б
Ц И Ш В
Ч Щ Й Г
Ш Ж Ц Д
Щ Ъ Ё Е
Ъ Д Ф Ё
Ь Э Н Ж
Ы В Т З
Э Я П  И
Ю пробел Р Ё
Я А Ы К
пробел Ё Л Л


Реализация:

Создаем массивы из всех исходных алфавитов и называем их:

  • alf - Исходный алфавит;
  • firstalf - Первый подстановочный алфавит;
  • secondalf - Второй подстановочный алфавит;
  • thirdalf -  Третий подстановочный алфавит.
Вводим входную строку.
Если в входной строке есть символы не из исходного алфавита выводим ошибку и завершаем работу программы.
Парсим каждый элемент входной строки:
  • Если индекс рассматриваемого элемента делиться по модулю на 3 без остатка, то находим индекс данного элемента в исходном алфавите и в выходную строку out добавляем элемент третьего подстановочного алфавита с данным индексом.
  • Если индекс рассматриваемого элемента делиться по модулю на 2 без остатка. то находим индекс данного элемента в исходном алфавите и в выходную строку out добавляем элемент второго подстановочного алфавита с данным индексом.
  • Во всех других случаях, находим индекс данного элемента в исходном алфавите и в выходную строку out добавляем элемент первого подстановочного алфавита с данным индексом.
Выводим полученную зашифрованную строку.
Для дешифрации используется такой же алгоритм с единственным отличием, что мы ищем элемент с индексом не в исходном алфавите а в соответствующем алфавите и добавляем в out2 элемент из исходного алфавита с данным индексом.


Код:

import sys

# Исходный алфавит. Создаем из него массив
rualf = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ "
alf = []
for x in rualf:
    alf.append(x)
print ("Original alf:",rualf)

# Первый подстановочный алфавит
first = "БЮГЫЕЬЗШЙЦЛФНТПРСОУМХКЧИЩЖЪДЭВЯ АЁ"
firstalf=[]
for x in first:
    firstalf.append(x)
print ("First alf:",first)

#Второй подстановочный алфавит
second = "СОУМКХЧИЩЖЪДЭВЯАБЮГ ЕЬЗШЙЦЁФНТПРЫЛ"
secondalf = []
for x in second:
    secondalf.append(x)
print ("Second alf:",second)

# Третий подстановочный алфавит
third = "МНОПРСТУФХЦЧШЩЪЬЫЭЮЯ АБВГДЕЁЖЗИЙКЛ"
thirdalf = []
for x in third:
    thirdalf.append(x)
print ("Third alf:",third)

# Функция кодирования
def crypt(inp):
    out = ""
    i = 1
    try:
        for x in inp:
            if (i%3==0):
                y = rualf.index(x)
                out += thirdalf[y]
            elif (i%2==0):
                y = rualf.index(x)
                out += secondalf[y]
            else:
                y = rualf.index(x)
                out += firstalf[y]
            i += 1
    except:
        print ("Обнаружен символ, которого нет в исходном алфавите (русский).")
        sys.exit()
    return out

# Функция декодирования
def decrypt(cryptotext):
    out2 = ""
    i = 1
    for x in cryptotext:
        if (i%3==0):
            y = third.index(x)
            out2 += alf[y]
        elif (i%2==0):
            y = second.index(x)
            out2 += alf[y]
        else:
            y = first.index(x)
            out2 += alf[y]
        i += 1
    return out2

#Главная функция
def main():
    print ("Please enter Original text:")
    inp = input()
    print ("Original text: ",inp)
    cryptotext = crypt(inp)
    print ("Crypt text: ",cryptotext)
    decryptotext = decrypt(cryptotext)
    print ("Decrypt text: ",decryptotext)

main()

Комментариев нет:

Отправить комментарий