The Caesar cipher is an ancient encryption algorithm used by Julius Caesar. It encrypts letters by shifting them over by a certain number of places in the alphabet. We call the length of shift the key. For example, if the key is 3, then A becomes D, B becomes E, C becomes F, and so on. To decrypt the message, you must shift the encrypted letters in the opposite direction. This program lets the user encrypt and decrypt messages according to this algorithm.
In modern times, the Caesar cipher isn’t very sophisticated, but that makes it ideal for beginners. The program in Project 7, “Caesar Hacker,” can brute-force through all 26 possible keys to decrypt messages, even if you don’t know the original key. Also, if you encrypt the message with the key 13, the Caesar cipher becomes identical to Project 61, “ROT 13 Cipher.” Learn more about the Caesar cipher at https://en.wikipedia.org/wiki/Caesar_cipher. If you’d like to learn about ciphers and code breaking in general, you can read my book Cracking Codes with Python (No Starch Press, 2018; https://nostarch.com/crackingcodes/).
When you run caesarcipher.py, the output will look like this:
Caesar Cipher, by Al Sweigart [email protected]
Do you want to (e)ncrypt or (d)ecrypt?
> e
Please enter the key (0 to 25) to use.
> 4
Enter the message to encrypt.
> Meet me by the rose bushes tonight.
QIIX QI FC XLI VSWI FYWLIW XSRMKLX.
Full encrypted text copied to clipboard.
Caesar Cipher, by Al Sweigart [email protected]
Do you want to (e)ncrypt or (d)ecrypt?
> d
Please enter the key (0 to 26) to use.
> 4
Enter the message to decrypt.
> QIIX QI FC XLI VSWI FYWLIW XSRMKLX.
MEET ME BY THE ROSE BUSHES TONIGHT.
Full decrypted text copied to clipboard.
Like most cipher programs, the Caesar cipher works by translating characters into numbers, performing some math operations on those numbers, and translating the numbers back into text characters. In the context of ciphers, we call these text characters symbols. Symbols can include letters, numeric digits, and punctuation marks, each of which gets assigned a unique integer. In the case of the Caesar cipher program, the symbols are all letters, and their integers are their position in the SYMBOLS
string: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
.
1. """Caesar Cipher, by Al Sweigart [email protected]
2. The Caesar cipher is a shift cipher that uses addition and subtraction
3. to encrypt and decrypt letters.
4. More info at: https://en.wikipedia.org/wiki/Caesar_cipher
5. View this code at https://nostarch.com/big-book-small-python-projects
6. Tags: short, beginner, cryptography, math"""
7.
8. try:
9. import pyperclip # pyperclip copies text to the clipboard.
10. except ImportError:
11. pass # If pyperclip is not installed, do nothing. It's no big deal.
12.
13. # Every possible symbol that can be encrypted/decrypted:
14. # (!) You can add numbers and punctuation marks to encrypt those
15. # symbols as well.
16. SYMBOLS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
17.
18. print('Caesar Cipher, by Al Sweigart [email protected]')
19. print('The Caesar cipher encrypts letters by shifting them over by a')
20. print('key number. For example, a key of 2 means the letter A is')
21. print('encrypted into C, the letter B encrypted into D, and so on.')
22. print()
23.
24. # Let the user enter if they are encrypting or decrypting:
25. while True: # Keep asking until the user enters e or d.
26. print('Do you want to (e)ncrypt or (d)ecrypt?')
27. response = input('> ').lower()
28. if response.startswith('e'):
29. mode = 'encrypt'
30. break
31. elif response.startswith('d'):
32. mode = 'decrypt'
33. break
34. print('Please enter the letter e or d.')
35.
36. # Let the user enter the key to use:
37. while True: # Keep asking until the user enters a valid key.
38. maxKey = len(SYMBOLS) - 1
39. print('Please enter the key (0 to {}) to use.'.format(maxKey))
40. response = input('> ').upper()
41. if not response.isdecimal():
42. continue
43.
44. if 0 <= int(response) < len(SYMBOLS):
45. key = int(response)
46. break
47.
48. # Let the user enter the message to encrypt/decrypt:
49. print('Enter the message to {}.'.format(mode))
50. message = input('> ')
51.
52. # Caesar cipher only works on uppercase letters:
53. message = message.upper()
54.
55. # Stores the encrypted/decrypted form of the message:
56. translated = ''
57.
58. # Encrypt/decrypt each symbol in the message:
59. for symbol in message:
60. if symbol in SYMBOLS:
61. # Get the encrypted (or decrypted) number for this symbol.
62. num = SYMBOLS.find(symbol) # Get the number of the symbol.
63. if mode == 'encrypt':
64. num = num + key
65. elif mode == 'decrypt':
66. num = num - key
67.
68. # Handle the wrap-around if num is larger than the length of
69. # SYMBOLS or less than 0:
70. if num >= len(SYMBOLS):
71. num = num - len(SYMBOLS)
72. elif num < 0:
73. num = num + len(SYMBOLS)
74.
75. # Add encrypted/decrypted number's symbol to translated:
76. translated = translated + SYMBOLS[num]
77. else:
78. # Just add the symbol without encrypting/decrypting:
79. translated = translated + symbol
80.
81. # Display the encrypted/decrypted string to the screen:
82. print(translated)
83.
84. try:
85. pyperclip.copy(translated)
86. print('Full {}ed text copied to clipboard.'.format(mode))
87. except:
88. pass # Do nothing if pyperclip wasn't installed.
After entering the source code and running it a few times, try making experimental changes to it. The comments marked with (!)
have suggestions for small changes you can make. You can expand the encryptable symbols by adding characters to the SYMBOLS
string.
Try to find the answers to the following questions. Experiment with some modifications to the code and rerun the program to see what effect the changes have.
SYMBOLS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
on line 16 to SYMBOLS = 'ABC'
?0
?translated = ''
on line 56?key = int(response)
on line 45?translated = translated + SYMBOLS[num]
on line 76 to translated = translated + symbol
?