Here is an interesting problem: how to generate sufficiently random but semi-pronounceable, and easy to remember passwords. I mean, putting together a random password generator is easy – just pick bunch of random character from a pool of printable symbols and you are done. The problem with this method is that more often than not you end up with something like Bz9hFtT[mp1 which while reasonably strong, is virtually impossible to remember. I don’t know about you, but my brain is just not very good at holding on to random sequences of characters and/or numbers.

To me best passwords are ones that are not dictionary words, but retain word-like qualities. You can sort of sound them out in your head. How do you accomplish that though? The simplest way is to alternate vowels and consonants. The algorithm goes something like this:

1. Pick a random character
2. If the last character was a consonant, next pick a vowel
3. If the last character was a vowel, pick a consonant/number/sybmol
4. Consonants should common, numbers/symbols should be rare

You could improve this a bit by allowing strings of 2-3 consonants to happen every once in a while. If you really wanted to be fancy you could attach weight to each character based on the statistical frequency in which it tends to appear in natural language. But the above works surprisingly well – especially if you choose to break up your passwords into 4 or 6 character syllables. Here are some sample passwords I generated using the above method:

• tExU-1EXi
• vacy-6Ate
• WiRU-xOZi
• RoFu-RYKy
• TANA-He8O
• Y1U-MA5E-fU

Pretty decent for something this simple, eh? I thin that RoFu-RYKy and WiRU-xOZi are my favorites from this list.

Here is a sample python code I used to accomplish this magic:

```# ct: dd66d04b-ce35-420a-9b64-63817bd43fa9

def next_char(last_char, use_symbols=False):
""" Return a randomly generated character """

vowels = ['a', 'e', 'i', 'o', 'u', 'y', 'A', 'E', 'I', 'O', 'U', 'Y']
consonants = [i for i in string.letters if i not in vowels]

# Using a reduced set of symbols for clarity
symbols = ["@", "#", "\$", "%", "&"]

if not last_char:
return random.choice(string.letters)

if last_char in consonants or last_char in string.digits or last_char in symbols:
return random.choice(vowels)

if last_char in vowels:
pct = random.randint(0, 100)

if pct < 60:
return random.choice(consonants)
elif pct < 90:
return random.choice(string.digits)
elif use_symbols:
return random.choice(symbols)
else:
return random.choice(consonants)

""" Generate random password given length """

passwd = ""
last = ""

for i in range(length):

last = next_char(last)

passwd += last;

if i%4==3 and i!=length-1:
passwd += "-"

return passwd```

In case you were wondering, I have a working demo here. The code could probably be improved, but feel free to use it if you want to. See if you can retain the GUID number up top. I decided to follow Jeff Atwood's advice and start tagging the code snippets with a unique ID's. This way if they for some strange reason become part of your code base you will know where they came from and you can always google that ID to check for updates. This is probably not that important in a trivial piece of code like this one, but I'm doing it to get in the habit.

This entry was posted in programming and tagged . Bookmark the permalink.

### 5 Responses to Generating Random Pronoucable Passwords

1. JKjoker says:

the pronunciation might be easy to remember but the change from caps to nocaps seems too random, maybe if they had a pattern like caps only on the edges of a syllables or all caps/nocaps syllables (easier to remember than for each individual letter) or you might as well program different pattern rules and choose one randomly before generating the password (inform the pattern to the user along with the generated password)

also using rare printable symbols (those that bruteforce programs tend not to use or try last) as randomized syllable separators instead of always – would improve the strength of the passwords without affecting the pronunciation (the symbol for all separators should be the same in each password tho)

2. The Debian repositories have a tool called pwgen (doesn’t seem to have a website) whose purpose is to generate pronounceable passwords. I’ve known about it for awhile but have not put it to use. I think your program does a better job than pwgen anyway.

Then there’s my personal favorite, Diceware, and its variations. I find Diceware passwords to be much easier to type, in addition to memorize. But they are much longer than usual.

I like the GUID code idea you’re using. Thanks for pointing that out.

3. SapientIdiot says:

I used to generate extreamly random and long passwords, and remember them by writing them down over and over again (then burn the paper i used), but eventually i just fell back to using phrases or abbrivations of phrases i can easily remember and throwing in random symbols and capitalizations.

Wouldnt using a script like this make passwords more easily crackable if someone knew that it was this script that was used to generate the password?

4. says:

@ JKjoker:

Hmm… That’s a good idea. I figured randomizing capitalization would improve password strength without making them too difficult to memorize.

Thanks for digging out that Coding Horror link. I tried finding it the other day, and then gave up. :P

@ SapientIdiot:

Yes, it technically does make it more easily crackable than a completely random password. On the other hand it is probably vastly superior to using “password123” or “qwerty123” or short words vulnerable to a dictionary attack.It’s a compromise.

5. k00pa says:

Looks like useful script…

Maybe I should update my passwords with this :P