From 2bd8dbc6db568667b3ef333cc64fc81bc5aa2641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20M=C3=BCller?= Date: Sun, 17 Oct 2021 16:54:25 +0200 Subject: [PATCH] Adding util method to replace invalid input characters - Also better type hints --- chapter_one/Multiplikative_Chiffre.py | 9 +++-- chapter_one/Permutations-Chiffre.py | 17 ++++++--- chapter_one/Tausch-Chiffre.py | 9 +++-- utils/CipherUtils.py | 50 ++++++++++++++++++++++++++- 4 files changed, 74 insertions(+), 11 deletions(-) diff --git a/chapter_one/Multiplikative_Chiffre.py b/chapter_one/Multiplikative_Chiffre.py index b885df6..d4ceedf 100644 --- a/chapter_one/Multiplikative_Chiffre.py +++ b/chapter_one/Multiplikative_Chiffre.py @@ -1,9 +1,10 @@ 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): +def encrypt_text(cleartext: str, key: int) -> str: """ Encrypts the given text with the given key :param cleartext: The text to encrypt @@ -14,6 +15,8 @@ def encrypt_text(cleartext: str, key: int): if key not in ALLOWED_KEYS: raise AttributeError + cleartext = cu.transform_invalid_chars(cleartext) + resulting = '' for char in cleartext: @@ -24,7 +27,7 @@ def encrypt_text(cleartext: str, key: int): return resulting -def decrypt_text(ciphertext: str, key: int): +def decrypt_text(ciphertext: str, key: int) -> str: """ Decrypts the given ciphertext with the given key :param ciphertext: The text to decrypt @@ -47,7 +50,7 @@ def decrypt_text(ciphertext: str, key: int): return resulting -def _get_key_reverse(key: int): +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 diff --git a/chapter_one/Permutations-Chiffre.py b/chapter_one/Permutations-Chiffre.py index 849ee4d..8252e0d 100644 --- a/chapter_one/Permutations-Chiffre.py +++ b/chapter_one/Permutations-Chiffre.py @@ -1,15 +1,19 @@ import random from utils import AlphabetUtils as au +from utils import CipherUtils as cu -def encrypt_text(cleartext: str, key: [int]): +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 a list of indices of the alphabet, so [0...25] shuffled :return: The encrypted text """ + + cleartext = cu.transform_invalid_chars(cleartext) + resulting = '' for char in cleartext: @@ -21,7 +25,7 @@ def encrypt_text(cleartext: str, key: [int]): return resulting -def decrypt_text(ciphertext: str, key: [int]): +def decrypt_text(ciphertext: str, key: [int]) -> str: """ Decrypts the given ciphertext with the given key :param ciphertext: The text to decrypt @@ -39,7 +43,7 @@ def decrypt_text(ciphertext: str, key: [int]): return resulting -def generate_key(): +def generate_key() -> [int]: """ Generates a key that can be used for this cipher. :return: The key as a list of indices @@ -51,7 +55,12 @@ def generate_key(): return indices -def generate_key_with_keyword(keyword: str): +def generate_key_with_keyword(keyword: str) -> [int]: + """ + Generates a key that can be used for this cipher by using the given keyword as a starting point + :param keyword: The keyword to use to generate the key + :return: The key as a list of indices + """ result = [] for char in keyword: diff --git a/chapter_one/Tausch-Chiffre.py b/chapter_one/Tausch-Chiffre.py index 44c0131..0d2bc73 100644 --- a/chapter_one/Tausch-Chiffre.py +++ b/chapter_one/Tausch-Chiffre.py @@ -1,9 +1,10 @@ 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, key1: int, key2: int): +def encrypt_text(cleartext: str, key1: int, key2: int) -> str: """ Encrypts the given text with the given keys :param cleartext: The text to encrypt @@ -19,6 +20,8 @@ def encrypt_text(cleartext: str, key1: int, key2: int): if key2 < 0 or key2 > 25: raise AttributeError + cleartext = cu.transform_invalid_chars(cleartext) + resulting = '' for char in cleartext: @@ -29,7 +32,7 @@ def encrypt_text(cleartext: str, key1: int, key2: int): return resulting -def decrypt_text(ciphertext: str, key1: int, key2: int): +def decrypt_text(ciphertext: str, key1: int, key2: int) -> str: """ Decrypts the given ciphertext with the given keys :param ciphertext: The text to decrypt @@ -57,7 +60,7 @@ def decrypt_text(ciphertext: str, key1: int, key2: int): return resulting -def _get_key_reverse(key: int): +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 diff --git a/utils/CipherUtils.py b/utils/CipherUtils.py index d48b766..bc08b22 100644 --- a/utils/CipherUtils.py +++ b/utils/CipherUtils.py @@ -1,10 +1,40 @@ -import AlphabetUtils as au +from utils import AlphabetUtils as au + +GERMAN_FREQUENCY_PROFILE = [ + 0.0651, + 0.0189, + 0.0306, + 0.0508, + 0.1740, + 0.0166, + 0.0301, + 0.0476, + 0.0755, + 0.0027, + 0.0121, + 0.0344, + 0.0253, + 0.0978, + 0.0251, + 0.0079, + 0.0002, + 0.0700, + 0.0727, + 0.0615, + 0.0435, + 0.0067, + 0.0189, + 0.0003, + 0.0004, + 0.0113 + ] def calculate_frequency(text: str, fancy_printing: bool = False): """ Calculates the frequency of every letter in the german alphabet for the given text :param text: The text to calculate the letter frequency for + :param fancy_printing: Whether to print the frequencies to the console :return: A list of frequencies, where index 0 contains the frequency of a in percent and so on. """ occurrence_count = [0 for i in range(26)] @@ -26,6 +56,24 @@ def calculate_frequency(text: str, fancy_printing: bool = False): return occurrence_frequency +def transform_invalid_chars(input: str) -> str: + """ + Transforms invalid characters like german umlauts into their allowed alternatives + :param input: The text to check + :return: The improved text + """ + res = input + res = res.replace('ä', 'ae') + res = res.replace('A', 'Ae') + res = res.replace('ö', 'oe') + res = res.replace('Ö', 'Oe') + res = res.replace('ü', 'ue') + res = res.replace('Ü', 'Ue') + res = res.replace('ß', 'ss') + + return res + + if __name__ == '__main__': print( calculate_frequency('Hier den Text eingeben, für den die Wahrscheinlichkeiten berechnet werden sollen', True))