Аффинный шифр 3-го порядка
написать аффинный шифр 3-го(к-го) порядка, допустимым с текстом "hello world" к примеру, сам шифр имеет матрицу, выступающую в роли ключа, и вспомогательный ключ, на который по идее мы должны умножать нашу матрицу, то есть первый ключ. Сообщение разбивается на k-граммы. Каждая k-грамма X замещается k-граммой. Каждая k-грамма X' криптотекста замещается k-граммой D(X’)=A’X’+S’, где A’=A-1 и S’=–A’S – расшифровывающий ключ. Ниже мой код, однако мне кажется легче будет создать новый, проблема возникает на процессе декодирования, на сколько я понимаю:
import numpy as np
def affine_encrypt(message, key1, key2):
message = message.upper().replace(" ", "")
letter_to_num = {chr(i + 65): i for i in range(26)}
num_to_letter = {i: chr(i + 65) for i in range(26)}
ciphertext = ""
nums = [letter_to_num[char] for char in message]
n = len(nums)
m = int(np.ceil(n / 3))
nums = np.pad(nums, (0, m * 3 - n), mode='constant')
nums = np.reshape(nums, (m, 3))
# шифр с использованием матричного умножения
prod = np.dot(nums, key1)
key2 = np.tile(key2.T, (m, 1))
nums = np.mod(prod + key2, 26)
# Преобразование чисел обратно в буквы и добавление к зашифрованному тексту
for row in nums:
for num in row:
ciphertext += num_to_letter[num]
return ciphertext
def affine_decrypt(ciphertext, key1, key2):
letter_to_num = {chr(i + 65): i for i in range(26)}
num_to_letter = {i: chr(i + 65) for i in range(26)}
plaintext = ""
nums = [letter_to_num[char] for char in ciphertext]
# Преобразование чисел в матрицу
n = len(nums)
m = int(np.ceil(n / 3))
nums = np.pad(nums, (0, m * 3 - n), mode='constant')
nums = np.reshape(nums, (m, 3))
# дешифровка с использованием матричного умножения
key2 = np.tile(key2.T, (m, 1))
try:
nums = np.round(np.mod(np.dot(nums - key2, np.linalg.inv(key1)), 26)).astype(int)
except np.linalg.LinAlgError:
print("Error: Key 1 is not invertible!")
return ""
# Преобразование чисел обратно в буквы и добавление в открытый текст
for row in nums:
for num in row:
plaintext += num_to_letter[num]
plaintext = plaintext[:n]
return plaintext
key1 = np.array([[4, 3, 2], [1, 2, 1], [3, 2, 4]]) # 1 ключ
key2 = np.array([[1], [2], [3]]) # 2 ключ
message = "Hello world"
ciphertext = affine_encrypt(message, key1, key2)
print("Ciphertext:", ciphertext)
plaintext = affine_decrypt(ciphertext, key1, key2)
print("Plaintext:", plaintext)
Вот результат выполнения: Ciphertext: OBNVDXDWONLJ Plaintext: DSDDQGWPBDAA
Источник: Stack Overflow на русском