Chapter 6 - Hacking The Caesar Cipher With Brute-Force
Chapter 6 - Hacking The Caesar Cipher With Brute-Force
6
HACKING THE CAESAR CIPHER WITH BRUTE-FORCE
“Arab scholars . . . invented cryptanalysis, the science of unscrambling a message without knowledge of the key.”
—Simon Singh, The Code Book
We can hack the Caesar cipher by using a cryptanalytic technique called brute-force. A brute-force attack tries
every possible decryption key for a cipher. Nothing stops a cryptanalyst from guessing one key, decrypting the
ciphertext with that key, looking at the output, and then moving on to the next key if they didn’t find the secret
message. Because the brute-force technique is so effective against the Caesar cipher, you shouldn’t actually use
the Caesar cipher to encrypt secret information.
Ideally, the ciphertext would never fall into anyone’s hands. But Kerckhoffs’s principle (named after the 19th-
century cryptographer Auguste Kerckhoffs) states that a cipher should still be secure even if everyone knows
how the cipher works and someone else has the ciphertext. This principle was restated by the 20th-century
mathematician Claude Shannon as Shannon’s maxim: “The enemy knows the system.” The part of the cipher that
keeps the message secret is the key, and for the Caesar cipher this information is very easy to find.
caesarHacker.py
Notice that much of this code is the same as the code in the original Caesar cipher program. This is because
the Caesar cipher hacker program uses the same steps to decrypt the message.
Because the decrypted output for key 13 is plain English, we know the original encryption key must have
been 13.
https://inventwithpython.com/cracking/chapter6.html 2/6
3/5/2023 Chapter 6 - Hacking the Caesar Cipher with Brute-Force
Setting Up Variables
The hacker program will create a message variable that stores the ciphertext string the program tries to decrypt.
The SYMBOLS constant variable contains every character that the cipher can encrypt:
The value for SYMBOLS needs to be the same as the value for SYMBOLS used in the Caesar cipher program that
encrypted the ciphertext we’re trying to hack; otherwise, the hacker program won’t work. Note that there is a
single space between the 0 and ! in the string value.
The range() function takes one integer argument and returns a value of the range data type. Range values
can be used in for loops to loop a specific number of times according to the integer you give the function. Let’s
try an example. Enter the following into the interactive shell:
The for loop will loop three times because we passed the integer 3 to range().
More specifically, the range value returned from the range() function call will set the for loop’s variable to
the integers from 0 to (but not including) the argument passed to range(). For example, enter the following into
the interactive shell:
This code sets the variable i to the values from 0 to (but not including) 6, which is similar to what line 8
in caesarHacker.py does. Line 8 sets the key variable with the values from 0 to (but not including) 66. Instead of
hard-coding the value 66 directly into our program, we use the return value from len(SYMBOLS) so the program
will still work if we modify SYMBOLS.
The first time the program execution goes through this loop, key is set to 0, and the ciphertext in messageis
decrypted with key 0. (Of course, if 0 is not the real key, message just “decrypts” to nonsense.) The code inside
https://inventwithpython.com/cracking/chapter6.html 3/6
3/5/2023 Chapter 6 - Hacking the Caesar Cipher with Brute-Force
the for loop from lines 9 through 31, which we’ll explain next, are similar to the original Caesar cipher program
and do the decrypting. On the next iteration of line 8’s for loop, key is set to 1 for the decryption.
Although we won’t use it in this program, you can also pass two integer arguments to the range() function
instead of just one. The first argument is where the range should start, and the second argument is where the
range should stop (up to but not including the second argument). The arguments are separated by a comma:
The variable i will take the value from 2 (including 2) up to the value 6 (but not including 6).
It’s important that we reset translated to a blank string at the beginning of this for loop; otherwise, the text
that was decrypted with the current key will be added to the decrypted text in translated from the last iteration
in the loop.
Lines 16 to 30 are almost the same as the code in the Caesar cipher program in Chapter 5 but are slightly
simpler because this code only has to decrypt:
13. # The rest of the program is almost the same as the Caesar program:
14.
15. # Loop through each symbol in message:
16. for symbol in message:
17. if symbol in SYMBOLS:
18. symbolIndex = SYMBOLS.find(symbol)
In line 16, we loop through every symbol in the ciphertext string stored in message. On each iteration of this
loop, line 17 checks whether symbol exists in the SYMBOLS constant variable and, if so, decrypts it. Line
18’s find() method call locates the index where symbol is in SYMBOLS and stores it in a variable
called symbolIndex.
Then we subtract the key from symbolIndex on line 19 to decrypt:
This subtraction operation may cause translatedIndex to become less than zero and require us to “wrap
around” the SYMBOLS constant when we find the position of the character in SYMBOLS to decrypt to. Line 22
checks for this case, and line 23 adds 66 (which is what len(SYMBOLS) returns) if translatedIndex is less
than 0.
https://inventwithpython.com/cracking/chapter6.html 4/6
3/5/2023 Chapter 6 - Hacking the Caesar Cipher with Brute-Force
Now that translatedIndex has been modified, SYMBOLS[translatedIndex] will evaluate to the decrypted
symbol. Line 26 adds this symbol to the end of the string stored in translated:
Line 30 just adds the unmodified symbol to the end of translated if the value was not found in
the SYMBOL set.
The argument for the print() function call is a string value that uses string formatting (also called string
interpolation). String formatting with the %s text places one string inside another one. The first %s in the string
gets replaced by the first value in the parentheses at the end of the string.
Enter the following into the interactive shell:
In this example, first the string 'world' is inserted into the string 'Hello %s!' in place of the %s. It works
as though you had concatenated the part of the string before the %s with the interpolated string and the part of the
string after the %s. When you interpolate multiple strings, they replace each %s in order.
String formatting is often easier to type than string concatenation using the + operator, especially for large
strings. And, unlike with string concatenation, you can insert non-string values such as integers into the string.
Enter the following into the interactive shell:
The integer 42 is inserted into the string without any issues when you use interpolation, but when you try to
concatenate the integer, it causes an error.
Line 33 of caesarHacker.py uses string formatting to create a string that has the values in both
the key and translated variables. Because key stores an integer value, we use string formatting to put it in a
string value that is passed to print().
Summary
https://inventwithpython.com/cracking/chapter6.html 5/6
3/5/2023 Chapter 6 - Hacking the Caesar Cipher with Brute-Force
The critical weakness of the Caesar cipher is that there aren’t many possible keys that can be used to encrypt.
Any computer can easily decrypt with all 66 possible keys, and it takes a cryptanalyst only a few seconds to look
through the decrypted messages to find the one in English. To make our messages more secure, we need a cipher
that has more potential keys. The transposition cipher discussed in Chapter 7 can provide this security for us.
PRACTICE QUESTION
Answers to the practice questions can be found on the book’s website
at https://www.nostarch.com/crackingcodes/.
1. Break the following ciphertext, decrypting one line at a time because each line has a different key.
Remember to escape any quote characters:
qeFIP?eGSeECNNS,
5coOMXXcoPSZIWoQI,
avnl1olyD4l'ylDohww6DhzDjhuDil,
z.GM?.cEQc. 70c.7KcKMKHA9AGFK,
?MFYp2pPJJUpZSIJWpRdpMFY,
ZqH8sl5HtqHTH4s3lyvH5zH5spH4t pHzqHlH3l5K
Zfbi,!tif!xpvme!qspcbcmz!fbu!nfA
https://inventwithpython.com/cracking/chapter6.html 6/6