Generating a random passphrase

Disclaimer

I’m not going to go into all the politics of passwords. Users are always trying to balance security with convenience. The point of this tutorial is not to say “This is how you generate the best password.” It’s more like “If you want to generate a random passphrase, this is one way to do it in Python.” The passwords you generate with this won’t be stuff like 6ZFtK!’z[^R88Rgd, but they also won’t be password or 123456.

Creating and running the file

Open up your text editor and save the empty text file as PassphraseGenerator.py on your desktop. In the text editor type in

print("This Python script runs!")

and run it.

If you ran the code correctly, you should see This Python script runs! appear after you hit Enter.

Any time you make changes to your script, you’ll have to run it again to see the changes. If you’re use PyCharm, you can just run it again. If you’re using a text editor, you’ll have to save your changes first and then run it again.

Getting the words file contents

On macOS (and most Linux distributions), there’s a file that has a dictionary of words. It’s usually located at /usr/share/dict/words, which is a hidden directory of sorts (you won’t find it by just opening up your file browser and clicking around).

So we’re going to check that the file exists and then display its contents.

First, import the os module:

import os

all this does is allow us to access other files on the computer. Now we’re going to say what file we want to check for and then check to see if the file exists:

import os

# This is where it is for macOS and Linux. You may have to adjust this path for Windows or other operating systems.
words_location = '/usr/share/dict/words'

# Check to see if the location exists
if os.path.isfile(words_location):

   # Get the words into a list we can use
   with open(words_location) as file:
      words_list = file.read().splitlines()

   # Show the list
   print(words_list)

else:
   print(f"{words_location} does not exist, so we can't get words out")

Remember that indents (with spaces or tabs, but use one or the other, instead of mixing and matching) are important and that you can copy and paste code, but I highly recommend you retype the code to learn it a bit better.

We can use os.path.isfile() because we imported the os module earlier. All that does is check “Is there a file at this location?”

The next set of lines just opens the file as variable file and then puts each read line in file into a list called words_list.

Once each word is in the list, we just print out the whole list (which is long!) just so you can see what the word looks like.

If the file location does not exist, we just have a message to say “Hey, there is no /usr/share/dict/words file.” Sad trumpet.

Go ahead and run your Python script as you did before. You should get a list of all the words in the dictionary.

Getting a random word from the dictionary

Okay. We don’t actually want the entire dictionary, we just want random words. Before we get random words (plural), though, let’s just start with one random word (singular).

So just as we needed the os module to access files on the computer, we’ll need to import the random module to get random selections. import os
import random

# This is where it is for macOS and Linux. You may have to adjust this path for Windows or other operating systems.
words_location = '/usr/share/dict/words'

# Check to see if the location exists
if os.path.isfile(words_location):

   # Get the words into a list we can use
   with open(words_location) as file:
      words_list = file.read().splitlines()

   # Pick a random word
   random_word = random.choice(words_list).title()

   # Print the random word
   print(random_word)

else:
   print(f"{words_location} does not exist, so we can't get words out")

We’re also, instead of printing out the whole list, going to select a random choice from the words list, put in title case (so Otters instead of otters, for example), and then print that random word out.

Try it out. In fact, run your script a few times so you can see how a (probably different) random word is picked every time.

Creating a passphrase instead of a word

So instead of one random word, we actually want to have a couple or several random words. Let’s set a minimum length for how long this “phrase” is going to be and keep building the phrase until it gets to (or beyond) that length.

import os
import random

# This is where it is for macOS and Linux. You may have to adjust this path for Windows or other operating systems.
words_location = '/usr/share/dict/words'

# Minimum number of characters the "phrase" should be
passphrase_min_length = 14

# Check to see if the location exists
if os.path.isfile(words_location):

   # Get the words into a list we can use
   with open(words_location) as file:
      words_list = file.read().splitlines()

   # Initialize a blank passphrase we'll add to
   passphrase = ''
  
   # Keep adding random words to the passphrase until it's as long as the minimum length
   while len(passphrase) < passphrase_min_length:

      # Pick a random word
      random_word = random.choice(words_list).title()

      passphrase += random_word

   print(passphrase)

else:
   print(f"{words_location} does not exist, so we can't get words out")

Note that in addition to setting a minimum length, we're also setting a blank passphrase to start with, because the while loop just keeps adding to the passphrase (that’s what the += sign means), and you can’t add to something that doesn’t exist, so we have to start with blank and then keep adding to it.

Adding spaces between words

What if we want to add some spaces? Well, we can do that by adding a space and the random word to the passphrase instead of just the random word:

import os
import random

# This is where it is for macOS and Linux. You may have to adjust this path for Windows or other operating systems.
words_location = '/usr/share/dict/words'

# Minimum number of characters the "phrase" should be
passphrase_min_length = 14

# Check to see if the location exists
if os.path.isfile(words_location):

   # Get the words into a list we can use
   with open(words_location) as file:
      words_list = file.read().splitlines()

   # Initialize a blank passphrase we'll add to
   passphrase = ''
  
   # Keep adding random words to the passphrase until it's as long as the minimum length
   while len(passphrase) < passphrase_min_length:

      # Pick a random word
      random_word = random.choice(words_list).title()

      passphrase += ' ' + random_word

   print(passphrase)

else:
   print(f"{words_location} does not exist, so we can't get words out")

Go ahead and run that. Do you see the problem? There's a space before the first word. We want spaces between the words but not before the first word, so we'll have to put a little if/then logic in there: If it’s the first time we’re running this (i.e., the passphrase is blank right now), let’s not put in the space. Otherwise, let’s put in the space.

import os
import random

# This is where it is for macOS and Linux. You may have to adjust this path for Windows or other operating systems.
words_location = '/usr/share/dict/words'

# Minimum number of characters the "phrase" should be
passphrase_min_length = 14

# Check to see if the location exists
if os.path.isfile(words_location):

   # Get the words into a list we can use
   with open(words_location) as file:
      words_list = file.read().splitlines()

   # Initialize a blank passphrase we'll add to
   passphrase = ''
  
   # Keep adding random words to the passphrase until it's as long as the minimum length
   while len(passphrase) < passphrase_min_length:

      # Pick a random word
      random_word = random.choice(words_list).title()

      # Check to see if this the first time through the loop
      if passphrase != '':
         # If it's not the first time, add a space
         passphrase += ' '
      
      # Regardless of whether it's the first time or not, add the random word
      passphrase +=  random_word

   print(passphrase)

else:
   print(f"{words_location} does not exist, so we can't get words out")

Now if you run it, you should see a space between words but not before the first word. Also try running it with a longer minimum than 14.

Extra Challenges

If your mastery over this exercise is pretty good, try to challenge yourself with a few tweaks:

  • Make it so the random words aren’t too long? (It’s up to you to decide what “too long” means.)
  • Generate multiple passphrases at once instead of only one phrase at a time?
  • Ask the user for input on what parameters she’d like to change (the maximum length, etc.).

Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *