Cracking Codes with Python

Cracking Codes with Python

An Introduction to Building and Breaking Ciphers
by Al Sweigart
January 2018, 424 pp.
ISBN-13: 
978-1-59327-822-9


Download Chapter 2: Programming in the Interactive Shell

Learn how to program in Python while making and breaking ciphers—algorithms used to create and send secret messages!

After a crash course in Python programming basics, you’ll learn to make, test, and hack programs that encrypt text with classical ciphers like the transposition cipher and Vigenère cipher. You’ll begin with simple programs for the reverse and Caesar ciphers and then work your way up to public key cryptography, the type of encryption used to secure today’s online transactions, including digital signatures, email, and Bitcoin.

Each program includes the full code and a line-by-line explanation of how things work. By the end of the book, you’ll have learned how to code in Python and you’ll have the clever programs to prove it!

You’ll also learn how to:

  • Combine loops, variables, and flow control statements into real working programs
  • Use dictionary files to instantly detect whether decrypted messages are valid English or gibberish
  • Create test programs to make sure that your code encrypts and decrypts correctly
  • Code (and hack!) a working example of the affine cipher, which uses modular arithmetic to encrypt a message
  • Break ciphers with techniques such as brute-force and frequency analysis

There’s no better way to learn to code than to play with real programs. Cracking Codes with Python makes the learning fun!

Author Bio 

Al Sweigart is a professional software developer who teaches programming to kids and adults. He is the author of Automate the Boring Stuff with Python, Invent Your Own Computer Games with Python, and Scratch Programming Playground, also from No Starch Press. His programming tutorials can be found at https://inventwithpython.com.

Table of contents 

Introduction

Chapter 1: Making Paper Cryptography Tools
Chapter 2: Programming in the Interactive Shell
Chapter 3: Strings and Writing Programs
Chapter 4: The Reverse Cipher
Chapter 5: The Caesar Cipher
Chapter 6: Hacking the Caesar Cipher with Brute Force
Chapter 7: Encrypting with the Transposition Cipher
Chapter 8: Decrypting with the Transposition Cipher
Chapter 9: Programming a Program to Test Your Program
Chapter 10: Encrypting and Decrypting Files
Chapter 11: Detecting English Programmatically
Chapter 12: Hacking the Transposition Cipher
Chapter 13: A Modular Arithmetic Module for the Affine Cipher
Chapter 14: Programming the Affine Cipher
Chapter 15: Hacking the Affine Cipher
Chapter 16: Programming the Simple Substitution Cipher
Chapter 17: Hacking the Simple Substitution Cipher
Chapter 18: Programming the Vigenère Cipher
Chapter 19: Frequency Analysis
Chapter 20: Hacking the Vigenère Cipher
Chapter 21: The One-Time Pad Cipher
Chapter 22: Finding and Generating Prime Numbers
Chapter 23: Generating Keys for the RSA Cipher
Chapter 24: Programming the RSA Cipher

Appendix: Debugging Python Code

View the detailed Table of Contents
View the Index

Reviews 

“Definitely worth the read even as an experienced Python developer. I learned more about cryptography and even a few new Python tricks.”
—Ray Doyle, The Ethical Hacker Network

“I recommend this book for anyone who wants to learn Python/programming and is interested in security or puzzles.”
—Jeanne Boyarsky, Code Ranch

“A fantastic programming and cryptography course for any high school-aged child.”
The Old Schoolhouse Magazine

Extra Stuff 
Updates 

On pages 209 and 212: Line 14 of the simpleSubcipher.py program which reads "if keyIsValid(myKey):" should instead read "if not keyIsValid(myKey):"

Page 281: Line 23 of the vigenereDictionaryHacker.py program which reads "for word in lines:" should instead read "for word in words:"

Page 325

The code for primeNum.py should be changed from this:

83.
84. # See if any of the low prime numbers can divide num:
85. for prime in LOW_PRIMES:
86. if (num % prime == 0):
87. return False
88.

...to this:

83. # See if any of the low prime numbers can divide num:
84. for prime in LOW_PRIMES:
85. if (num == prime):
86. return True
87. if (num % prime == 0):
88. return False

Page 333

The section of text starting from the second paragraph that reads:

Line 85 loops through each of the prime numbers in the LOW_PRIMES list:

84. # See if any of the low prime numbers can divide num:
85. for prime in LOW_PRIMES:
86. if (num % prime == 0):
87. return False

The integer in num is modded by each prime number using the mod operator on line 86, and if the result evaluates to 0, we know that prime divides num so num is not prime. In that case, line 87 returns False.

Those are the two quick tests we’ll perform to determine whether a
number is prime. If the execution continues past line 87, the rabinMiller()
function checks num’s primality.

Should be changed to this:

Line 84 loops through each of the prime numbers in the LOW_PRIMES list:

83. # See if any of the low prime numbers can divide num:
84. for prime in LOW_PRIMES:
85. if (num == prime):
86. return True
87. if (num % prime == 0):
88. return False

If the integer in num is the same as prime, then obviously num must be a prime number and line 86 returns True.
The integer in num is modded by each prime number using the mod operator on line 87, and if the result evaluates to 0 , we know that prime divides num so num is not prime. In that case, line 88 returns False .

Those are the three quick tests we’ll perform to determine whether a
number is prime. If the execution continues past line 88, the rabinMiller()
function checks num’s primality.