One of the simplest ciphers is one in which each letter is replaced by some other letter; nonletters are unchanged. For example, if every letter were replaced by the letter after it in the alphabet (with z → a), the message Attack at dawn! would become Buubdl bu ebxo!
Your assignment will be to cipher and decipher messages, using a slightly more complex scheme.
Save your program as simple_cipher.py.
As above, enciphering will replace each letter in a message with a (probably) different letter, and will leave all spaces and punctuation unchanged.
blueberry. The word should not be more than 13 characters long.blueberryrstuvwxyz.blueberryrstuvwxyzabcdefghijklmnopqrstuvwxyzbluerystvwxzacdfghijkmnopq.| Plain | a b c d e f g h i j k l m n o p q r s t u v w x y z |
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ |
|
| Cipher | b l u e r y s t v w x z a c d f g h i j k m n o p q |
With this cipher, Attack at dawn! becomes Bjjbux bj ebnc!
You don't need to exactly follow the above steps, so long as the result is the same. For example, you might start by removing duplicate letters from the secret word.
Hint: It's easier to build up a new string one letter at a time, than it is to remove letters from within a string.
Make two dictionaries: One for enciphering a message, another for deciphering an enciphered message. Each is just the reverse of the other.
Continuing the above example, the dictionary for enciphering a message would be , while the one for deciphering would be {'b':'a', 'l':'b', 'u':'c', 'e':'d', ...}. (But remember, the order of entries in a dictionary is undefined and irrelevant.)
Why two dictionaries? Dictionaries contain key:value entries. It's much faster and easier to look up the value associated with a key, than it is to look up the key associated with a value. Also, keys have to be unique (you can't have two or more identical keys in the same dictionary); values do not have to be unique (although they will be in this case).
Hint: The dictionary get method can be very helpful.
Provide two methods, encipher(secret_word, plaintext_message) and decipher(secret_word, enciphered_message). Each of these will return the result as a string; neither should print anything.
To encipher or decipher a message, simply take each character of the message in turn, use it as a key in the corresponding dictionary, and add the value to a message you are building up. If the key isn't in the dictionary, just copy it unchanged.
You also need to preserve case, so Attack becomes Bjjbux, not bjjbux. You can do this with a few simple tests, or by putting more entries in the dictionaries.
Also provide a main method which asks the user whether to encipher or decipher, asks for a secret word, asks for a message, and prints the result. This is the only method that should do any input or output.
Do test-driven development (TDD). You should have tests for every method except main.
All the usual rules apply. In addition, try to keep your code as short and readable as possible, and avoid code duplication as much as possible.
We will run your main method, and will use our own unit tests for your encipher and decipher functions. We will also do spot checks for style, especially for overly long functions.