from itertools import cycle import string alpha = string.ascii_lowercase plainText = input("Enter your plaintext to be encrypted: ") userKey = input("Enter your alphabetical key; exits on invalid character: ").lower() cipherText = '' cycKey = cycle(userKey) # Caesar/ROT Function def rotateChar(s: str, rotate: int): out = '' boolUpper = s.isupper() s = s.lower() if s not in alpha: out = s elif s in alpha and alpha.index(s) + rotate > 25: if boolUpper: out = alpha[((alpha.index(s) + rotate) - 25) - 1].upper() else: out = alpha[((alpha.index(s) + rotate) - 25) - 1] else: if boolUpper: out = alpha[alpha.index(s) + rotate].upper() else: out = alpha[alpha.index(s) + rotate] return out # Check validity of key; for demonstration purposes I only accept alphabet characters for char in userKey: if char.lower() not in alpha: print("Invalid key; quitting.") quit() # Create nested list(s) with the proper ROT number for each string in the plaintext refList = [] for char, rot in zip([char for char in plainText if char.lower() in alpha], cycKey): if char.lower() in alpha: refList.append([char, alpha.index(rot)]) # Iterate through original plaintext and rotate when a legal character is at index 0 of refList then pop index 0. for char in plainText: if refList and char == refList[0][0]: cipherText += rotateChar(char, refList[0][1]) refList.pop(0) else: cipherText += char print("Ciphertext:", cipherText)