If you find any typos, please email them to [email protected]. (Apologies in advance if I haven't posted your errata submission yet or failed to give credit. Please email me to correct this.)

## Chapter 3 - The Interactive Shell

The code listing after "Remember, variables store single values, not expressions." should be `spam = 10 + 5`

instead of `spam = 15`

.

## Chapter 9 - Decrypting with the Transposition Cipher

**Table 6-2** is the truth table for the `or`

operator, but it actually shows the `and`

operator's truth table. *(Thanks to Agavriloaie Constantin)*

**Page 135**, the interactive shell should look like this:

```
>>> not False and False # not False evaluates first
True
>>> not (False and False) # (False and False) evaluates first
False
```

*(Thanks to Omer Chohan)*

## Chapter 15 - The Affine Cipher

**Line 75 of affineCipher.py** has the code `if cryptomath.gcd(keyA, len(SYMBOLS)) != 1:`

which should be `if cryptomath.gcd(keyA, len(SYMBOLS)) == 1:`

*(Thanks to Patrick Dwyer)*

**Page 216** should read "(that is, it is less than 0)" *(Thanks to Scott Parkis)*

## Chapter 17 - The Simple Substitution Cipher

One of the "Topics Covered In This Chapter" is "The Set data type and set() function". It is actually covered in Chapter 21, "Hacking the Vigenere Cipher". *(Thanks to Dave Briccetti)*

## Chapter 18 - Hacking The Simple Substitution Cipher

**Page 267**'s interactive shell example should read `>>> letterMapping = simpleSubHacker.removeSolvedLettersFromMapping(letterMapping)`

*(Thanks to Scott Parkis)*

## Chapter 20 - Hacking The Simple Substitution Cipher

**Page 306** should say "Line 39 loops..." instead of "Line 44 loops..." *(Thanks to Scott Parkis)*

## Chapter 23 - Finding Prime Numbers

**Line 13 of rabinMiller.py** is `# keep halving s until it is even (and use t`

when it should be `# keep halving s while it is even (and use t`

*(Thanks to Lianxiang Yang.)*

## Chapter 24 - Public Key Cryptography and the RSA Cipher

**Line 111 of rsaCipher.py** is `sys.exit('ERROR: Block size is %s bits and key size is %s bits. The RSA cipher requires the block size to be equal to or greater than the key size. Either decrease the block size or use different keys.' % (blockSize * 8, keySize))`

when it should be `sys.exit('ERROR: Block size is %s bits and key size is %s bits. The RSA cipher requires the block size to be equal to or less than the key size. Either increase the block size or use different keys.' % (blockSize * 8, keySize))`

*(Thanks to Lianxiang Yang.)*

**Line 146 of rsaCipher.py** is `sys.exit('ERROR: Block size is %s bits and key size is %s bits. The RSA cipher requires the block size to be equal to or greater than the key size. Did you specify the correct key file and encrypted file?' % (blockSize * 8, keySize))`

*(Thanks to Lianxiang Yang.)*

The text on line 411 is "The readFromFileAndDecrypt() function also has a check that the block size is equal to or greater than the key size." when it should read "The readFromFileAndDecrypt() function also has a check that the block size is equal to or less than the key size." *(Thanks to Lianxiang Yang.)*

**The link on page 415** is incorrect. It should me http://invpy.com/morehacking instead of http://invp.com/morehacking. *(Thanks to Bilal Khan.)*

**Page 399** should read "Line 40 places" instead of "Line 140 places". *(Thanks to Yanfei Yu.)*

**Table 24-4** should have indices from 0 to 127, not 0 to 128. *(Thanks to Yanfei Yu.)*

**Page 86** has an extra space after "a" on line 16: `a bcde`

. Also, the code segment shows this code as being in caesarCipher.py instead of caesarCipher2.py. *(Thanks to Mark M.)*