From 7f9a4f7adcc0aa18077d2ab43443411d87dc6d23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20M=C3=BCller?= Date: Fri, 15 Oct 2021 16:40:23 +0200 Subject: [PATCH] #5: Implementing Tausch-Chiffre --- chapter_one/Tausch-Chiffre.py | 75 +++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 chapter_one/Tausch-Chiffre.py diff --git a/chapter_one/Tausch-Chiffre.py b/chapter_one/Tausch-Chiffre.py new file mode 100644 index 0000000..761d30c --- /dev/null +++ b/chapter_one/Tausch-Chiffre.py @@ -0,0 +1,75 @@ +from utils import AlphabetUtils as au + +ALLOWED_KEYS = [1, 3, 5, 7, 9, 11, 15, 17, 19, 21, 23, 25] + + +def encrypt_text(key1: int = 11, key2: int = 7, cleartext: str = 'BonkRocks'): + """ + Encrypts the given text with the given keys + :param key1: The first key. Has to be between 1 and 25 and a coprime to 26 + :param key2: The second key. Has to be between 0 and 26 + :param cleartext: The text to encrypt + :return: The encrypted text + """ + # key1 has to be coprime to 26 + if key1 not in ALLOWED_KEYS: + raise AttributeError + + # key2 has to be between 0 and 25 + if key2 < 0 or key2 > 25: + raise AttributeError + + resulting = '' + + for char in cleartext: + index = au.get_index_of_letter(char) + newIndex = (index * key1 + key2) % 26 + resulting += au.get_letter_at_index(newIndex) + + return resulting + + +def decrypt_text(key1: int = 11, key2: int = 7, ciphertext: str = 'sfunmfdnx'): + """ + Decrypts the given ciphertext with the given keys + :param key1: The first key. Has to be between 1 and 25 and a coprime to 26 + :param key2: The second key. Has to be between 0 and 26 + :param ciphertext: The text to decrypt + :return: The decrypted text + """ + # key1 has to be coprime to 26 + if key1 not in ALLOWED_KEYS: + raise AttributeError + + # key2 has to be between 0 and 25 + if key2 < 0 or key2 > 25: + raise AttributeError + + decrypt_key1 = _get_key_reverse(key1) + + resulting = '' + + for char in ciphertext: + index = au.get_index_of_letter(char) + newIndex = ((index - key2) * decrypt_key1) % 26 + resulting += au.get_letter_at_index(newIndex) + + return resulting + + +def _get_key_reverse(key: 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()) + print(decrypt_text())