#!/usr/bin/python3 # -*- coding: utf-8 -*- # Vigenere Cipher (Polyalphabetic Substitution Cipher) # https://www.nostarch.com/crackingcodes (BSD Licensed) LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" def main() -> None: # This text can be copy/pasted from https://invpy.com/vigenereCipher.py: myMessage = """If there is no struggle there is no progress. Those \ who profess to favor freedom and yet deprecate agitation are men who wa\ nt crops without plowing up the ground; they want rain without thunder \ and lightning. They want the ocean without the awful roar of its many w\ aters. This struggle may be a moral one, or it may be a physical one, a\ nd it may be both moral and physical, but it must be a struggle. Power \ concedes nothing without a demand. It never did and it never will. -- F\ rederick Douglass""" myKey = "ASIMOV" myMode = "encrypt" # Set to either 'encrypt' or 'decrypt'. if myMode == "encrypt": translated = encryptMessage(myKey, myMessage) elif myMode == "decrypt": translated = decryptMessage(myKey, myMessage) print("%sed message:" % (myMode.title())) print(translated) print() print("The message has been copied to the clipboard.") def encryptMessage(key: str, message: str) -> str: return translateMessage(key, message, "encrypt") def decryptMessage(key: str, message: str) -> str: return translateMessage(key, message, "decrypt") def translateMessage(key: str, message: str, mode: str) -> str: translated = [] # Stores the encrypted/decrypted message string. keyIndex = 0 key = key.upper() for symbol in message: # Loop through each symbol in message. num = LETTERS.find(symbol.upper()) if num != -1: # -1 means symbol.upper() was not found in LETTERS. if mode == "encrypt": num += LETTERS.find(key[keyIndex]) # Add if encrypting. elif mode == "decrypt": num -= LETTERS.find(key[keyIndex]) # Subtract if decrypting. num %= len(LETTERS) # Handle any wraparound. # Add the encrypted/decrypted symbol to the end of translated: if symbol.isupper(): translated.append(LETTERS[num]) elif symbol.islower(): translated.append(LETTERS[num].lower()) keyIndex += 1 # Move to the next letter in the key. if keyIndex == len(key): keyIndex = 0 else: # Append the symbol without encrypting/decrypting. translated.append(symbol) return "".join(translated) # If vigenereCipher.py is run (instead of imported as a module) call # the main() function. if __name__ == "__main__": main()