Do the same Caesar chipher as in the previous example but the time use ROT-3, that is rotate the letters three steps. Create two functions, one for coding messages and one for decoding them.
Hint:
You might want to use two dictionaries to solve this problem.
Here is the first version of the program. Look below for other solutions.
#Create two dictionaries. This one is used to encipher the message encipherkey = {'a' : 'd' ,'b' : 'e' ,'c' : 'f' ,'d' : 'g' ,'e' : 'h' ,'f' : 'i' ,'g' : 'j' ,'h' : 'k' , 'i' : 'l' ,'j' : 'm' ,'k' : 'n' ,'l' : 'o' ,'m' : 'p' ,'n' : 'q' ,'o' : 'r' ,'p' : 's' , 'q' : 't' ,'r' : 'u' ,'s' : 'v' ,'t' : 'w' ,'u' : 'x' ,'v' : 'y' ,'w' : 'z' ,'x' : 'a' , 'y' : 'b' ,'z' : 'c' ,'A' : 'D' ,'B' : 'E' ,'C' : 'F' ,'D' : 'G' ,'E' : 'H' ,'F' : 'I' , 'G' : 'J' ,'H' : 'K' ,'I' : 'L' ,'J' : 'M' ,'K' : 'N' ,'L' : 'O' ,'M' : 'P' ,'N' : 'Q' , 'O' : 'R' ,'P' : 'S' ,'Q' : 'T' ,'R' : 'U' ,'S' : 'V' ,'T' : 'W' ,'U' : 'X' ,'V' : 'Y' , 'W' : 'Z' ,'X' : 'A' ,'Y' : 'B' ,'Z' : 'C' } #And this one is used to decipher the message decipherkey = {'a' : 'x' ,'b' : 'y' ,'c' : 'z' ,'d' : 'a' ,'e' : 'b' ,'f' : 'c' ,'g' : 'd' ,'h' : 'e' , 'i' : 'f' ,'j' : 'g' ,'k' : 'h' ,'l' : 'i' ,'m' : 'j' ,'n' : 'k' ,'o' : 'l' ,'p' : 'm' , 'q' : 'n' ,'r' : 'o' ,'s' : 'p' ,'t' : 'q' ,'u' : 'r' ,'v' : 's' ,'w' : 't' ,'x' : 'u' , 'y' : 'v' ,'z' : 'w' ,'A' : 'X' ,'B' : 'Y' ,'C' : 'Z' ,'D' : 'A' ,'E' : 'B' ,'F' : 'C' , 'G' : 'D' ,'H' : 'E' ,'I' : 'F' ,'J' : 'G' ,'K' : 'H' ,'L' : 'I' ,'M' : 'J' ,'N' : 'K' , 'O' : 'L' ,'P' : 'M' ,'Q' : 'N' ,'R' : 'O' ,'S' : 'P' ,'T' : 'Q' ,'U' : 'R' ,'V' : 'S' , 'W' : 'T' ,'X' : 'U' ,'Y' : 'V' ,'Z' : 'W' } #This function uses the encipher dictionary def encode(text): result = "" for c in text: #Only look up letters if c.isalpha(): result += encipherkey[c] else: #Any other character will be stored as is result += c return result #This one is identical to the encode function except it uses the decipher dictionary def decode(text): result = "" for c in text: #Only look up letters if c.isalpha(): result += decipherkey[c] else: #Any other character will be stored as is result += c return result def main(): encoded = encode("This is my secret!") decoded = decode(encoded) print(encoded) print(decoded) if __name__ == '__main__': main()
Below is a better version of the program. Here we generate the dicitionaies in two functions and we pass the generated dictionaries to the encipher function so we can use it for both encryption and decryption.
#Instead of creating fixed dictionaries I decided to solve this #by creating to functions that generates the dictionaries #By doing this I can pass in a value for how many steps I want #the key dict to be rotated def create_encoding_dict(rot): #First we create the lower case letters encoding_dict = {} #a-z has the ascii values of 97-122 for i in range(97,123): #We need to check to see if it is time to wrap the alphabet around if i + rot < 122: encoding_dict[chr(i)] = chr(i+rot) else: #Yes wrap encoding_dict[chr(i)] = chr(i -26+rot) #Now take care of the upper case letters A-Z (65-90) for i in range(65,91): #We need to check to see if it is time to wrap the alphabet around if i + rot < 90: encoding_dict[chr(i)] = chr(i+rot) else: #YEs wrap encoding_dict[chr(i)] = chr(i -26+rot) return encoding_dict def create_decoding_dict(rot): #First we create the lower case letters decoding_dict = {} #a-z has the ascii values of 97-122 for i in range(97,123): #We need to check to see if it is time to wrap the alphabet around if i - rot >= 97: decoding_dict[chr(i)] = chr(i-rot) else: #YEs wrap decoding_dict[chr(i)] = chr(i +26-rot) #Now take care of the upper case letters A-Z (65-90) for i in range(65,91): #We need to check to see if it is time to wrap the alphabet around if i - rot >= 65: decoding_dict[chr(i)] = chr(i-rot) else: #Yes wrap decoding_dict[chr(i)] = chr(i +26-rot) return decoding_dict #If we pass in the key dict to use we can use the same function for encoding and decoding def encipher(text, key): result = "" for c in text: #Only look up letters if c.isalpha(): result += key[c] else: #Any other character will be stored as is result += c return result def main(): enchipherKey = create_encoding_dict(3) decipherKey = create_decoding_dict(3) encoded = encipher("This is a secret message!",enchipherKey) decoded = encipher(encoded,decipherKey) print(encoded) print(decoded)
This final version does not use any functions but instead it uses list comprehension and itertools chain function to generate the tables. Those are used with the maketrans and translate functions from the string class
from itertools import chain def main(): cleartext = "This is a secret message" ciphertext = cleartext.translate(str.maketrans( "".join([chr(x) for x in chain(range(65,91),range(97,123))]), "".join(chain([chr(65+(x+3)%26) for x in range(26)], [chr(97+(x+3)%26) for x in range(26)])))) cleartext = ciphertext.translate(str.maketrans( "".join(chain([chr(65+(x+3)%26) for x in range(26)], [chr(97+(x+3)%26) for x in range(26)])), "".join([chr(x) for x in chain(range(65,91),range(97,123))]))) print(ciphertext) print(cleartext)