Krypto_Grundlagen/chapter_one/Multiplikative_Chiffre.py

69 lines
1.7 KiB
Python
Raw Normal View History

from utils import AlphabetUtils as au
from utils import CipherUtils as cu
ALLOWED_KEYS = [1, 3, 5, 7, 9, 11, 15, 17, 19, 21, 23, 25]
def encrypt_text(cleartext: str, key: int) -> str:
"""
Encrypts the given text with the given key
:param cleartext: The text to encrypt
:param key: The key to use. Has to be between 1 and 25 and a coprime to 26.
:return: The encrypted text
"""
# Key has to be coprime to 26
if key not in ALLOWED_KEYS:
raise AttributeError
cleartext = cu.transform_invalid_chars(cleartext)
resulting = ''
for char in cleartext:
index = au.get_index_of_letter(char)
2021-10-15 15:57:35 +00:00
new_index = (index * key) % 26
resulting += au.get_letter_at_index(new_index)
return resulting
def decrypt_text(ciphertext: str, key: int) -> str:
"""
Decrypts the given ciphertext with the given key
:param ciphertext: The text to decrypt
:param key: The key to use. Has to be between 1 and 25 and a coprime to 26.
:return: The decrypted text
"""
# Key has to be coprime to 26
if key not in ALLOWED_KEYS:
raise AttributeError
decrypt_key = _get_key_reverse(key)
resulting = ''
for char in ciphertext:
index = au.get_index_of_letter(char)
2021-10-15 15:57:35 +00:00
new_index = (index * decrypt_key) % 26
resulting += au.get_letter_at_index(new_index)
return resulting
def _get_key_reverse(key: int) -> int:
"""
Calculates the decryption key (inverse of the original key) based on the following formula:
s * s' mod 26 = 1
:param key: The key to reverse
:return: The decryption key
"""
for possibility in ALLOWED_KEYS:
if (key * possibility) % 26 == 1:
return possibility
if __name__ == '__main__':
print(encrypt_text('BonkRocks', 11))
print(decrypt_text('lyngfywgq', 11))