LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def main() -> None:
message = input("Enter message: ")
key = input("Enter key [alphanumeric]: ")
mode = input("Encrypt/Decrypt [e/d]: ")
if mode.lower().startswith("e"):
mode = "encrypt"
translated = encrypt_message(key, message)
elif mode.lower().startswith("d"):
mode = "decrypt"
translated = decrypt_message(key, message)
print(f"\n{mode.title()}ed message:")
print(translated)
def encrypt_message(key: str, message: str) -> str:
"""
>>> encrypt_message('HDarji', 'This is Harshil Darji from Dharmaj.')
'Akij ra Odrjqqs Gaisq muod Mphumrs.'
"""
return translate_message(key, message, "encrypt")
def decrypt_message(key: str, message: str) -> str:
"""
>>> decrypt_message('HDarji', 'Akij ra Odrjqqs Gaisq muod Mphumrs.')
'This is Harshil Darji from Dharmaj.'
"""
return translate_message(key, message, "decrypt")
def translate_message(key: str, message: str, mode: str) -> str:
translated = []
key_index = 0
key = key.upper()
for symbol in message:
num = LETTERS.find(symbol.upper())
if num != -1:
if mode == "encrypt":
num += LETTERS.find(key[key_index])
elif mode == "decrypt":
num -= LETTERS.find(key[key_index])
num %= len(LETTERS)
if symbol.isupper():
translated.append(LETTERS[num])
elif symbol.islower():
translated.append(LETTERS[num].lower())
key_index += 1
if key_index == len(key):
key_index = 0
else:
translated.append(symbol)
return "".join(translated)
if __name__ == "__main__":
main()
The Vigenere cipher is a famous toy cipher. It was invented in 1553 by the Italian cryptographer Giovan Battista Bellaso but for centuries was attributed to the 16th-century French cryptographer Blaise de Vigenère, who devised a similar cipher in 1586.
It is easy to encrypt and decrypt but at the same time, it is easy to intercept and crack this cipher. It is a polyalphabetic substitution cipher, meaning that the same letter of the alphabet can be replaced by different letters depending on the key. The key is a word or phrase that is repeated to match the length of the message. Then the letters of the key are used to shift the letters of the message.
The Vigenere cipher is an improvement over the Caesar cipher. The Caesar cipher uses a single character as the key to shift the message. In contrast, the Vigenere cipher uses a word or a phrase as the key. This means that the same character occurring at different positions in the message will be shifted by different amounts. This makes it harder to crack the cipher.
checktheking
and the key is chess
, the key is repeated to match the length of the message. The key is now chesschessch
.Message | c | h | e | c | k | t | h | e | k | i | n | g |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Value | 3 | 8 | 5 | 3 | 11 | 20 | 8 | 5 | 11 | 9 | 14 | 7 |
Key | c | h | e | s | s | c | h | e | s | s | c | h |
Shift | 3 | 8 | 5 | 19 | 19 | 3 | 8 | 5 | 19 | 19 | 3 | 8 |
Cipher | f | p | j | q | z | w | p | j | z | z | c | p |
So the encrypted message is fpjqzwjpzzcp
.
Decryption is the inverse of encryption. It is is done by subtracting the shift value from the cipher value. The formula is $M_i = L((C_i - V(K_i)) \mod n)$ where everything is defined as above and $L$ is additionally defined as a function which converts a numerical value back to a letter.
Cipher | f | p | j | q | z | w | p | j | z | z | c | p |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Key | c | h | e | s | s | c | h | e | s | s | c | h |
Shift | 3 | 8 | 5 | 19 | 19 | 3 | 8 | 5 | 19 | 19 | 3 | 8 |
Value | 3 | 8 | 5 | 3 | 11 | 20 | 8 | 5 | 11 | 9 | 14 | 7 |
Message | c | h | e | c | k | t | h | e | k | i | n | g |
So the decrypted message is checktheking
, as expected.
The encryption is done by adding the shift value to the message value. So the time complexity is $O(n)$ where $n$ is the length of the message. We use a linear data structure such as an array to store the message and the key. So the space complexity is $O(n)$.
Decryption is similar to encryption (except for the subtraction operation). So time and space complexity are the same as for encryption - $O(n)$.