Help Review Code for the Cryptography and Code Breaking Book

I have the source code written for my next book, “Hacking Secret Ciphers with Python” (formerly “Become a Code Breaker with Python”). (You can download the rough draft.)

The programs all implement classic cryptographic ciphers (Caesar cipher, simple substitution, etc.) as well as programs that can crack them. I’m posting it for public review so people can make any suggestions for edits. The code is loaded on github here:

https://github.com/asweigart/codebreaker

These programs are for a book that teaches computer programming in Python 3 to complete beginners, as well as teaching amateur cryptography. My aim for the programs are:

  • Simple – Is the code arranged in a way that requires the least amount of prerequisite knowledge? Is there a chunk of code that should have more comments? Is there a comment that doesn’t make sense?
  • Correctness – Is the cipher implemented correctly according to descriptions of the cipher?
  • Consistency – Is the naming and spacing of the code consistent with the other programs?

Things that are not goals for the source:

  • Security is not a primary concern. These are educational examples to teach basic cryptography concepts. Please withhold comments or criticisms that would be more appropriate for commercial encryption software. I understand that Python’s random module is not suitable for crypto. I understand that the RSA block cipher should use CBC mode instead of ECB mode. These decisions have been made because the point of this book is to teach and be simple for the reader to understand without going into the arcana of cryptography.
  • Efficient and elegant code is also not a primary concern. For example, I don’t use list comprehensions because it would add another programming topic to explain in the book. The code uses more lines than it probably needs too, but I’d rather have more-but-readable code than less-but-elegant code. If there’s an order of magnitude improvement that I can make, I’ll do it. Otherwise, a few extra seconds of processing time is worth having simpler code.
  • The code doesn’t dogmatically pass PEP-8. “Meh.”

Thanks to anyone who can offer their advice!

Read More

How Does Compression Work?

“Zip” programs that can compress multiple files into one smaller .zip file are fairly popular for downloads since the fewer bytes you have to download the faster it will download. But how do you compress files? Files are made up of ones and zeros, which can’t be squished like clothes into a tight suitcase.

Think about file compression working like this: If someone asked you what the lyrics to “99 bottles of beer on the wall” were, you would tell them:

“The song goes ’99 bottles of beer on the wall, 99 bottles of beer, take one down, pass it around, 98 bottles of beer on the wall’, and then you repeat the lyrics with a number one less than the previous time.”

The above sentence has 42 words in it. You wouldn’t tell the person literally the entire song (which has 2,376 words in it). The reason you don’t have to recite the full song is because of the song’s repetition. Repetition makes compression possible. We’ve achieved a 98% compression rate (counting by the word amount) with the description of the lyrics over the literal lyrics (42 words vs. 2,376 words), even though both detail exactly the same song.
(more…)

Read More

Need a Game Idea? A List of Game Mechanics and a Random Mechanic Mixer.

If you need an idea for a game, try this random game mechanic generator:

A full list is at the bottom of this page. I wanted to get fairly low level with these game mechanics, so I don’t include things such as “first person shooter” or “puzzles” (since those are, in my opinion, more correctly called genres).

Just to prove to myself that this generator isn’t worthless, I decided to make some small Python/Pygame games based off of it. These games are fairly rough since I wanted to rapidly produce them as proof-of-concepts. The mechanics that got selected were:

(more…)

Read More

16 Common Python Runtime Errors Beginners Find

Figuring out what Python’s error messages mean can be kind of tricky when you are first learning the language. Here’s a list of common errors that result in runtime error messages which will crash your program.

 

1) Forgetting to put a : at the end of an if, elif, else, for, while, class, or def statement. (Causes “SyntaxError: invalid syntax”)

This error happens with code like this:

if spam == 42
    print('Hello!')

 

2) Using = instead of ==. (Causes “SyntaxError: invalid syntax”)

The = is the assignment operator while == is the “is equal to” comparison operator. This error happens with code like this:

if spam = 42:
    print('Hello!')

 

3) Using the wrong amount of indentation. (Causes “IndentationError: unexpected indent” and “IndentationError: unindent does not match any outer indentation level” and “IndentationError: expected an indented block”)

Remember that the indentation only increases after a statement ending with a : colon, and afterwards must return to the previous indentation. This error happens with code like this:

print('Hello!')
    print('Howdy!')

…and this:

if spam == 42:
    print('Hello!')
  print('Howdy!')

…and this:

if spam == 42:
print('Hello!')

 

(more…)

Read More

Stop Using “print” for Debugging: A 5 Minute Quickstart Guide to Python’s logging Module

  • This tutorial is short.
  • To figure out bugs in your code, you might put in print statements/print() calls to display the value of variables.
  • Don’t do this. Use the Python logging module.

The logging is better than printing because:

  • It’s easy to put a timestamp in each message, which is very handy.
  • You can have different levels of urgency for messages, and filter out less urgent messages.
  • When you want to later find/remove log messages, you won’t get them confused for real print() calls.
  • If you just print to a log file, it’s easy to leave the log function calls in and just ignore them when you don’t need them. (You don’t have to constantly pull out print() calls.)

Using print is for coders with too much time on their hands. Use logging instead. Also, learn to use the Python debugger to debug bugs and Pylint to prevent bugs and make your code readable.

To print log messages to the screen, copy and paste this code:

import logging
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
logging.debug('This is a log message.')

To write log messages to a file, you can copy and paste this code (the only difference is in bold):

import logging
logging.basicConfig(filename='log_filename.txt', level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
logging.debug('This is a log message.')

Later runs of the program will append to the end of the log file, rather than overwrite the file.

To log messages to a file AND printed to the screen, copy and paste the following:
(more…)

Read More