How To Create Friendlier Random Passwords

One aspect of web applications which is almost always overlooked when it comes to accessibility is how easy any randomly generated string might be to read. If you’re lucky enough to have near perfect vision and have no learning or cognitive disabilities such as dyslexia, you mightn’t suffer from any problems reading randomly generated strings, but for many users distinguishing between zero and upper-case Os, ones and lower-case Ls, and even the letters b and d can be difficult.

So, in a recent project which required me to automatically generate passwords on request, I decided to put this into practice with the following PHP function:


function GenerateRandomString($length) {
	$characters = array('2', '3', '4', '5', '6', '7', '8', '9',
			'a', 'c', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm', 'p',
			'q', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
	$randomString = "";
	while(strlen($randomString) < $length) {
		$randomCharacterIndex = rand(0, count($characters) - 1);
		$randomString .= $characters[$randomCharacterIndex];
	}
	return $randomString;
}

Nothing too special going on here, except that the sometimes troublesome pairs of characters mentioned previously have been eliminated.

Now, it’s true that if we use this function to generate passwords, the passwords created will be less secure — this function can only create 285 (17 million) different five-character passwords whereas if I had included the missing characters this number would’ve been 365 (60 million). That’s a trade-off you’ll have to accept in return for fewer frustrated users having difficulty logging on to your site, which can be mitigated by forcing users to change their generated password to something chosen by them.

Note: If you know of any other characters that people have trouble with, leave a comment and I’ll update this post. Thanks!

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • http://www.magain.com/ mattymcg

    The difficulty in distinguishing between a 1 and an l has always been a huge source of frustration for me. Great idea Craig!

  • danh2000

    N1ce 1bea, 1 0ften strugg1e t00

  • http://www.afterlight.net.au AussieJohn

    I think it also depends quite a bit on the font used :-)

    I find with some fonts it can sometimes be hard to distinguish between the combination of r and n – so rn and m.

    If as you suggest some people have difficulty telling the difference between the letters b and d – mightn’t some people have the same problem with the p and q? Oh and let’s not forget about two consecutive letters such as a double v: vv – which might look like a w to some – again I think this depends on the font used.

  • http://www.craiga.id.au/ craiga

    @AussieJohn: It’s a good point you make re: ‘rn’ vs. ‘m’ and I’ll update the code to reflect that, but the difference between ‘b’ and ‘d’ vs. ‘p’ and ‘q’ is interesting. I’m no expert in the field and would be happy to be proven wrong, but in my reading it’s the fact that these letters rhyme that makes them confusing for dyslexics:

    “Their brains are not set up to deal with the sounds of words correctly, so they can’t match [sounds] to the right letters,” says Elise Temple, a neuroscience graduate student at Stanford and the lead author of the study. “The problem [lies] with matching letters to sounds rather than just letters themselves.” For example, a dyslexic has trouble distinguishing between letters that rhyme, such as ‘D’ and ‘B.’

    Does this mean every letter which ends with that ‘ee’ sound should be excluded? I’m not sure, but ‘b’ and ‘d’ seem to be the ones which cause the most confusion.

  • Just me

    Eek – do you really use uppercase function names? Personal preference obviously, but capitalized like that it looks like a class name.

  • http://www.afterlight.net.au AussieJohn

    @craiga: Interesting article – it’s good to have some light shed on that subject. This does raise another point though. Should we therefore also exclude the letters c, e, g, p, t and v. I know this is quite a stretch, but read aloud the following line and it makes sense.
    b, c, d, g, p, t, v

    Thoughts anyone?

  • Anonymous

    This is very quickly limiting the entropy of the password as these troublesome characters are being eliminated. You’ll need to increase the length of such passwords in order to gain a similar degree of security.

    From my understanding, the “random password” feature has often been used to allow users to generate very strong passwords. If this is the intended use, then the original code makes a lot of sense. However, catering the code to dyslexics seems like a fairly large cut in security when those users will probably opt to make their own passwords tailored to their needs specifically.

  • wwb_99

    Copy & Paste > Dyslexia

  • J. Pluijmers

    I would strongly advise against usage of these kind of passwords. It doesn’t take that long for a quadcore computer to calculate the 16 milion options and then put an automated free bruteforce tool to work with this data ie: Burp.

    If you have to use these kind of credentials I urge you to install some kind of CAPTCHA so automated attacks are unlikely to succeed.

    The forced password change might be a solution but a weak one at best. What if a user requested an account but never activates it? Then you still are verry vurnable to brute force.

  • Leo

    Sorry to say but script returns an error

    Notice: Undefined offset: 28 in ~ on line 15

    // fix
    $randomCharacterIndex = rand(0,count($characters)-1)

  • http://xslt2processor.sourceforge.net boen_robot

    Forigive me for saying this, but I’ve always hated this concept. The random password generation concept that is.

    Instead of trying to make users TYPE a random password, I’d much rathar educate them how to COPY it and then promt them to change it on first login. Or better yet, make them create a custom password upon registrations (like most sites do already).

    If generating a non-modifiable password is truly the only option, you have a bigger problem on your hands than your users’ acessibility problems.

  • http://m2i3.com myrdhrin

    I’m from the philosophy that to be effective a password has to be easy to remember. It does not matter how strong your password generation algorithm is if you have to write it down you it just lost all of it effectiveness.

    I published a pronounceable password generator on my website. It generates random passwords with letters, numbers and symbol but still manages to let your pronounce (hence) memorize them. Beats writing them down.

    The algorithm is public so you can tweak it to your taste.

    anyway… my 2 cents here

    Jean-Marc

  • http://www.afterlight.net.au AussieJohn

    To be honest, I was joining Craig and only looking at the accessibility point of view. I do agree that this limits the amount of available passwords a lot. When adding in another character to these passwords, e.g. a punctuation symbol, it allows the number of passwords to increase – and increase their general complexity also.

    I tend to use a pronounceable password generator as well – I have been using the one at webcogs for a few years now – I generally take one of their words and pre- or append a punctuation symbol and change the case of at least one letter.

  • http://www.craiga.id.au/ craiga

    @AussieJohn: I had the same thought, but the confusion between ‘b’ and ‘d’ seems to be the only one I could find documented. Perhaps it’s the visual similarity of the characters combined with the similar sounds?

    @Leo: Oops :) Fixed.

    @J. Pluijmers: Absolutely agree. Rather than use CAPTCHA, I’d implement some kind of system to disallow a large number of log in attempts within a period of time, or even lock out accounts once a threshold of bad attempts has been reached.

    @boen_robot: Part of the point of these passwords is they’re only used one time. Once the user authenticates with these passwords, they should be forced to enter one of their own choosing.

    @myrdhrin: I like the look of that pronounceable password generator. It could easily be extended to take into account the idea I’m suggesting here.

  • Roderik

    How about:


    import org.apache.commons.lang.RandomStringUtils;
    int size = 8;
    String password = RandomStringUtils.random(size, "23467abcdefhjkmnpqrstuvwxyz");

  • cod3.net

    instead of your while loop you can use array_rand()
    $randomString = array_rand($characters, $length);

  • Snapey

    Why does it have to be a password?

    I recently received a letter from the UK NHS and the letter contained two english words that had to be typed in as a combination. Four weeks later I can still remember that combination. When coupled with protection against a brute force attack this can be simple and effective.

    Having said that you of course have to be very careful when choosing words at random. Receiving an invitation that advises my pass phrase is stupid moron would not go down to well.

  • another1

    most of the people does copy and paste because it makes them feels so nerd…