CONTENTS IN DETAIL

ACKNOWLEDGMENTS

INTRODUCTION

Who Should Read This Book?

What’s in This Book?

How to Use This Book

Typing Source Code

Checking for Typos

Coding Conventions in This Book

Online Resources

Downloading and Installing Python

Windows Instructions

macOS Instructions

Ubuntu Instructions

Downloading pyperclip.py

Starting IDLE

Summary

1
MAKING PAPER CRYPTOGRAPHY TOOLS

What Is Cryptography?

Codes vs. Ciphers

The Caesar Cipher

The Cipher Wheel

Encrypting with the Cipher Wheel

Decrypting with the Cipher Wheel

Encrypting and Decrypting with Arithmetic

Why Double Encryption Doesn’t Work

Summary

Practice Questions

2
PROGRAMMING IN THE INTERACTIVE SHELL

Some Simple Math Expressions

Integers and Floating-Point Values

Expressions

Order of Operations

Evaluating Expressions

Storing Values with Variables

Overwriting Variables

Variable Names

Summary

Practice Questions

3
STRINGS AND WRITING PROGRAMS

Working with Text Using String Values

String Concatenation with the + Operator

String Replication with the * Operator

Getting Characters from Strings Using Indexes

Printing Values with the print() Function

Printing Escape Characters

Quotes and Double Quotes

Writing Programs in IDLE’s File Editor

Source Code for the “Hello, World!” Program

Checking Your Source Code with the Online Diff Tool

Using IDLE to Access Your Program Later

Saving Your Program

Running Your Program

Opening the Programs You’ve Saved

How the “Hello, World!” Program Works

Comments

Printing Directions to the User

Taking a User’s Input

Ending the Program

Summary

Practice Questions

4
THE REVERSE CIPHER

Source Code for the Reverse Cipher Program

Sample Run of the Reverse Cipher Program

Setting Up Comments and Variables

Finding the Length of a String

Introducing the while Loop

The Boolean Data Type

Comparison Operators

Blocks

The while Loop Statement

“Growing” a String

Improving the Program with an input() Prompt

Summary

Practice Questions

5
THE CAESAR CIPHER

Source Code for the Caesar Cipher Program

Sample Run of the Caesar Cipher Program

Importing Modules and Setting Up Variables

Constants and Variables

The for Loop Statement

An Example for Loop

A while Loop Equivalent of a for Loop

The if Statement

An Example if Statement

The else Statement

The elif Statement

The in and not in Operators

The find() String Method

Encrypting and Decrypting Symbols

Handling Wraparound

Handling Symbols Outside of the Symbol Set

Displaying and Copying the Translated String

Encrypting Other Symbols

Summary

Practice Questions

6
HACKING THE CAESAR CIPHER WITH BRUTE-FORCE

Source Code for the Caesar Cipher Hacker Program

Sample Run of the Caesar Cipher Hacker Program

Setting Up Variables

Looping with the range() Function

Decrypting the Message

Using String Formatting to Display the Key and Decrypted Messages

Summary

Practice Question

7
ENCRYPTING WITH THE TRANSPOSITION CIPHER

How the Transposition Cipher Works

Encrypting a Message by Hand

Creating the Encryption Program

Source Code for the Transposition Cipher Encryption Program

Sample Run of the Transposition Cipher Encryption Program

Creating Your Own Functions with def Statements

Defining a Function that Takes Arguments with Parameters

Changes to Parameters Exist Only Inside the Function

Defining the main() Function

Passing the Key and Message As Arguments

The List Data Type

Reassigning the Items in Lists

Lists of Lists

Using len() and the in Operator with Lists

List Concatenation and Replication with the + and * Operators

The Transposition Encryption Algorithm

Augmented Assignment Operators

Moving currentIndex Through the Message

The join() String Method

Return Values and return Statements

A return Statement Example

Returning the Encrypted Ciphertext

The __name__ Variable

Summary

Practice Questions

8
DECRYPTING WITH THE TRANSPOSITION CIPHER

How to Decrypt with the Transposition Cipher on Paper

Source Code for the Transposition Cipher Decryption Program

Sample Run of the Transposition Cipher Decryption Program

Importing Modules and Setting Up the main() Function

Decrypting the Message with the Key

The round(), math.ceil(), and math.floor() Functions

The decryptMessage() Function

Boolean Operators

Adjusting the column and row Variables

Calling the main() Function

Summary

Practice Questions

9
PROGRAMMING A PROGRAM TO TEST YOUR PROGRAM

Source Code for the Transposition Cipher Tester Program

Sample Run of the Transposition Cipher Tester Program

Importing the Modules

Creating Pseudorandom Numbers

Creating a Random String

Duplicating a String a Random Number of Times

List Variables Use References

Passing References

Using copy.deepcopy() to Duplicate a List

The random.shuffle() Function

Randomly Scrambling a String

Testing Each Message

Checking Whether the Cipher Worked and Ending the Program

Calling the main() Function

Testing the Test Program

Summary

Practice Questions

10
ENCRYPTING AND DECRYPTING FILES

Plain Text Files

Source Code for the Transposition File Cipher Program

Sample Run of the Transposition File Cipher Program

Working with Files

Opening Files

Writing to and Closing Files

Reading from a File

Setting Up the main() Function

Checking Whether a File Exists

The os.path.exists() Function

Checking Whether the Input File Exists with the os.path.exists() Function

Using String Methods to Make User Input More Flexible

The upper(), lower(), and title() String Methods

The startswith() and endswith() String Methods

Using These String Methods in the Program

Reading the Input File

Measuring the Time It Took to Encrypt or Decrypt

The time Module and time.time() Function

Using the time.time() Function in the Program

Writing the Output File

Calling the main() Function

Summary

Practice Questions

11
DETECTING ENGLISH PROGRAMMATICALLY

How Can a Computer Understand English?

Source Code for the Detect English Module

Sample Run of the Detect English Module

Instructions and Setting Up Constants

The Dictionary Data Type

The Difference Between Dictionaries and Lists

Adding or Changing Items in a Dictionary

Using the len() Function with Dictionaries

Using the in Operator with Dictionaries

Finding Items Is Faster with Dictionaries than with Lists

Using for Loops with Dictionaries

Implementing the Dictionary File

The split() Method

Splitting the Dictionary File into Individual Words

Returning the Dictionary Data

Counting the Number of English Words in message

Divide-by-Zero Errors

Counting the English Word Matches

The float(), int(), and str() Functions and Integer Division

Finding the Ratio of English Words in the Message

Removing Non-Letter Characters

The append() List Method

Creating a String of Letters

Detecting English Words

Using Default Arguments

Calculating Percentages

Summary

Practice Questions

12
HACKING THE TRANSPOSITION CIPHER

Source Code of the Transposition Cipher Hacker Program

Sample Run of the Transposition Cipher Hacker Program

Importing the Modules

Multiline Strings with Triple Quotes

Displaying the Results of Hacking the Message

Getting the Hacked Message

The strip() String Method

Applying the strip() String Method

Failing to Hack the Message

Calling the main() Function

Summary

Practice Questions

13
A MODULAR ARITHMETIC MODULE FOR THE AFFINE CIPHER

Modular Arithmetic

The Modulo Operator

Finding Factors to Calculate the Greatest Common Divisor

Multiple Assignment

Euclid’s Algorithm for Finding the GCD

Understanding How the Multiplicative and Affine Ciphers Work

Choosing Valid Multiplicative Keys

Encrypting with the Affine Cipher

Decrypting with the Affine Cipher

Finding Modular Inverses

The Integer Division Operator

Source Code for the Cryptomath Module

Summary

Practice Questions

14
PROGRAMMING THE AFFINE CIPHER

Source Code for the Affine Cipher Program

Sample Run of the Affine Cipher Program

Setting Up Modules, Constants, and the main() Function

Calculating and Validating the Keys

The Tuple Data Type

Checking for Weak Keys

How Many Keys Can the Affine Cipher Have?

Writing the Encryption Function

Writing the Decryption Function

Generating Random Keys

Calling the main() Function

Summary

Practice Questions

15
HACKING THE AFFINE CIPHER

Source Code for the Affine Cipher Hacker Program

Sample Run of the Affine Cipher Hacker Program

Setting Up Modules, Constants, and the main() Function

The Affine Cipher Hacking Function

The Exponent Operator

Calculating the Total Number of Possible Keys

The continue Statement

Using continue to Skip Code

Calling the main() Function

Summary

Practice Questions

16
PROGRAMMING THE SIMPLE SUBSTITUTION CIPHER

How the Simple Substitution Cipher Works

Source Code for the Simple Substitution Cipher Program

Sample Run of the Simple Substitution Cipher Program

Setting Up Modules, Constants, and the main() Function

The sort() List Method

Wrapper Functions

The translateMessage() Function

The isupper() and islower() String Methods

Preserving Cases with isupper()

Generating a Random Key

Calling the main() Function

Summary

Practice Questions

17
HACKING THE SIMPLE SUBSTITUTION CIPHER

Using Word Patterns to Decrypt

Finding Word Patterns

Finding Potential Decryption Letters

Overview of the Hacking Process

The Word Pattern Modules

Source Code for the Simple Substitution Hacking Program

Sample Run of the Simple Substitution Hacking Program

Setting Up Modules and Constants

Finding Characters with Regular Expressions

Setting Up the main() Function

Displaying Hacking Results to the User

Creating a Cipherletter Mapping

Creating a Blank Mapping

Adding Letters to a Mapping

Intersecting Two Mappings

How the Letter-Mapping Helper Functions Work

Identifying Solved Letters in Mappings

Testing the removeSolvedLetterFromMapping() Function

The hackSimpleSub() Function

The replace() String Method

Decrypting the Message

Decrypting in the Interactive Shell

Calling the main() Function

Summary

Practice Questions

18
PROGRAMMING THE VIGENÈRE CIPHER

Using Multiple Letter Keys in the Vigenère Cipher

Longer Vigenère Keys Are More Secure

Choosing a Key That Prevents Dictionary Attacks

Source Code for the Vigenère Cipher Program

Sample Run of the Vigenère Cipher Program

Setting Up Modules, Constants, and the main() Function

Building Strings with the List-Append-Join Process

Encrypting and Decrypting the Message

Calling the main() Function

Summary

Practice Questions

19
FREQUENCY ANALYSIS

Analyzing the Frequency of Letters in Text

Matching Letter Frequencies

Calculating the Frequency Match Score for the Simple Substitution Cipher

Calculating the Frequency Match Score for the Transposition Cipher

Using Frequency Analysis on the Vigenère Cipher

Source Code for Matching Letter Frequencies

Storing the Letters in ETAOIN Order

Counting the Letters in a Message

Getting the First Member of a Tuple

Ordering the Letters in the Message by Frequency

Counting the Letters with getLetterCount()

Creating a Dictionary of Frequency Counts and Letter Lists

Sorting the Letter Lists in Reverse ETAOIN Order

Sorting the Dictionary Lists by Frequency

Creating a List of the Sorted Letters

Calculating the Frequency Match Score of the Message

Summary

Practice Questions

20
HACKING THE VIGENÈRE CIPHER

Using a Dictionary Attack to Brute-Force the Vigenère Cipher

Source Code for the Vigenère Dictionary Hacker Program

Sample Run of the Vigenère Dictionary Hacker Program

About the Vigenère Dictionary Hacker Program

Using Kasiski Examination to Find the Key’s Length

Finding Repeated Sequences

Getting Factors of Spacings

Getting Every Nth Letters from a String

Using Frequency Analysis to Break Each Subkey

Brute-Forcing Through the Possible Keys

Source Code for the Vigenère Hacking Program

Sample Run of the Vigenère Hacking Program

Importing Modules and Setting Up the main() Function

Finding Repeated Sequences

Calculating the Factors of the Spacings

Removing Duplicates with the set() Function

Removing Duplicate Factors and Sorting the List

Finding the Most Common Factors

Finding the Most Likely Key Lengths

The extend() List Method

Extending the repeatedSeqSpacings Dictionary

Getting the Factors from factorsByCount

Getting Letters Encrypted with the Same Subkey

Attempting Decryption with a Likely Key Length

The end Keyword Argument for print()

Running the Program in Silent Mode or Printing Information to the User

Finding Possible Combinations of Subkeys

Printing the Decrypted Text with the Correct Casing

Returning the Hacked Message

Breaking Out of the Loop When a Potential Key Is Found

Brute-Forcing All Other Key Lengths

Calling the main() Function

Modifying the Constants of the Hacking Program

Summary

Practice Questions

21
THE ONE-TIME PAD CIPHER

The Unbreakable One-Time Pad Cipher

Making Key Length Equal Message Length

Making the Key Truly Random

Avoiding the Two-Time Pad

Why the Two-Time Pad Is the Vigenère Cipher

Summary

Practice Questions

22
FINDING AND GENERATING PRIME NUMBERS

What Is a Prime Number?

Source Code for the Prime Numbers Module

Sample Run of the Prime Numbers Module

How the Trial Division Algorithm Works

Implementing the Trial Division Algorithm Test

The Sieve of Eratosthenes

Generating Prime Numbers with the Sieve of Eratosthenes

The Rabin-Miller Primality Algorithm

Finding Large Prime Numbers

Generating Large Prime Numbers

Summary

Practice Questions

23
GENERATING KEYS FOR THE PUBLIC KEY CIPHER

Public Key Cryptography

The Problem with Authentication

Digital Signatures

Beware the MITM Attack

Steps for Generating Public and Private Keys

Source Code for the Public Key Generation Program

Sample Run of the Public Key Generation Program

Creating the main() Function

Generating Keys with the generateKey() Function

Calculating an e Value

Calculating a d Value

Returning the Keys

Creating Key Files with the makeKeyFiles() Function

Calling the main() Function

Hybrid Cryptosystems

Summary

Practice Questions

24
PROGRAMMING THE PUBLIC KEY CIPHER

How the Public Key Cipher Works

Creating Blocks

Converting a String into a Block

The Mathematics of Public Key Cipher Encryption and Decryption

Converting a Block to a String

Why We Can’t Hack the Public Key Cipher

Source Code for the Public Key Cipher Program

Sample Run of the Public Key Cipher Program

Setting Up the Program

How the Program Determines Whether to Encrypt or Decrypt

Converting Strings to Blocks with getBlocksFromText()

The min() and max() Functions

Storing Blocks in blockInt

Using getTextFromBlocks() to Decrypt

Using the insert() List Method

Merging the Message List into One String

Writing the encryptMessage() Function

Writing the decryptMessage() Function

Reading in the Public and Private Keys from Their Key Files

Writing the Encryption to a File

Decrypting from a File

Calling the main() Function

Summary

APPENDIX
DEBUGGING PYTHON CODE

How the Debugger Works

Debugging the Reverse Cipher Program

Setting Breakpoints

Summary

INDEX