diff --git a/chapter_two/Vigenere-Chiffre.py b/chapter_two/Vigenere-Chiffre.py new file mode 100644 index 0000000..1252267 --- /dev/null +++ b/chapter_two/Vigenere-Chiffre.py @@ -0,0 +1,84 @@ +from utils import AlphabetUtils as au + + +def encrypt_text(cleartext: str, keyword: str) -> str: + """ + Encrypts the given text with the given keyword + :param cleartext: The text to encrypt + :param keyword: The keyword to use + :return: The encrypted text + """ + + # If the ciphertext is longer than the keyword, we need to multiply the keyword + while len(cleartext) > len(keyword): + keyword += keyword + + resulting = '' + + for char_index in range(len(cleartext)): + char = cleartext[char_index] + key = keyword[char_index] + cipherchar = _get_corresponding_cipher(char, key) + resulting += cipherchar + + return resulting + + +def decrypt_text(ciphertext: str, keyword: str) -> str: + """ + Decrypts the given ciphertext with the given keyword + :param ciphertext: The text to decrypt + :param keyword: The keyword to use + :return: The decrypted text + """ + + # If the ciphertext is longer than the keyword, we need to multiply the keyword + while len(ciphertext) > len(keyword): + keyword += keyword + + resulting = '' + + for char_index in range(len(ciphertext)): + char = ciphertext[char_index] + key = keyword[char_index] + clearchar = _get_corresponding_char(char, key) + resulting += clearchar + + return resulting + + +def _get_corresponding_cipher(char: str, key: str) -> str: + """ + Calculates the corresponding cipher char for the given clearchar/keychar combination using the vigenere square + :param char: The cleartext char + :param key: The keyword char + :return: The cipher char + """ + char_index = au.get_index_of_letter(char) + key_index = au.get_index_of_letter(key) + + # Based on the layout of the vigenere square, this should in theory work + cipher_index = (char_index + key_index) % 26 + + return au.get_letter_at_index(cipher_index) + + +def _get_corresponding_char(cipher: str, key: str) -> str: + """ + Calculates the corresponding cleartext char for the given cipherchar/keychar combination using the vigenere square + :param cipher: The cipher char + :param key: The keyword char + :return: The cleartext char + """ + cipher_index = au.get_index_of_letter(cipher) + key_index = au.get_index_of_letter(key) + + # Based on the layout of the vigenere square, this should in theory work + char_index = (cipher_index - key_index) % 26 + + return au.get_letter_at_index(char_index) + + +if __name__ == '__main__': + print(encrypt_text('BonkRocks', 'SuperSecretKeyword')) + print(decrypt_text('ticoiggmj', 'SuperSecretKeyword'))