Last active
June 27, 2021 14:48
-
-
Save Pagliacii/734454d381a5af1e1e0c94e30e1e4bef to your computer and use it in GitHub Desktop.
Vigenère cipher. Ref: https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import string | |
import textwrap | |
import functools | |
def filter_not_upper(text: str) -> str: | |
return "".join(filter(lambda c: c in string.ascii_uppercase, text)) | |
def make_vigenere_table(inverse: bool = False) -> dict[str, dict[str, str]]: | |
vigenere_table = {} | |
base: int = ord("A") | |
for r in string.ascii_uppercase: | |
vigenere_table[r] = {} | |
for c in string.ascii_uppercase: | |
char = chr((ord(r) + ord(c)) % 26 + base) | |
if inverse: | |
vigenere_table[r][char] = c | |
else: | |
vigenere_table[r][c] = char | |
return vigenere_table | |
_encrypt_table = make_vigenere_table() | |
_decrypt_table = make_vigenere_table(True) | |
def encode(text: str, key: str, decrypt: bool = False) -> str: | |
result = "" | |
text = filter_not_upper(text.upper()) | |
key = filter_not_upper(key.upper()) | |
for word in textwrap.wrap(text, len(key)): | |
for r, c in zip(key, word): | |
if decrypt: | |
result += _decrypt_table[r][c] | |
else: | |
result += _encrypt_table[r][c] | |
return result | |
encrypt = functools.partial(encode, decrypt=False) | |
decrypt = functools.partial(encode, decrypt=True) | |
if __name__ == "__main__": | |
key = "lemon" | |
plaintext = "attackatdawn" | |
ciphertext = "lxfopvefrnhr" | |
assert encrypt(plaintext, key) == ciphertext.upper() | |
assert decrypt(ciphertext, key) == plaintext.upper() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment