Wednesday, July 2. 2008
Random thoughts on random strings
I first started to think about random strings when going through the process of registering an application for Windows Delegated Authentication service. As part of the application you are asked to provide a secret key. You want this to be difficult to guess so a random string is going to be best. Humans are astoundingly bad at being random and I just slapped the keyboard a few times until I felt I had the required 16 characters.
Writing some code to produce a fairly random string is incredibly easy. I've easily done it a dozen times or more. Though only because it is easier to re-write it than to find where I put the last one. They generally look something like this:
Running that creates a string something like '4e)+bSuv#kN^"O)f'. Suitably random. Well, pseudo-random.
This isn't the only way to generate a random string. You could take a similar approach but use the chr function instead.
The output is just as good and you don't have to type out every character you want to use. It was only recently, when working on a puzzle posted by Marco Tabini that I considered using chr. This got me thinking about what other options there were.
The uniqid function is one possibility. It does seem to take about twice as long as the first option listed here though. The manual page also contains this gem:
The emphasis is mine.
Other options include the hashing functions. md5 and sha1 would be two options.
There are a couple of problems with uniqid, md5 and sha1 though. Firstly they all return strings of a set length. You would need to use substr to get a shorter string and chain multiple calls together to get a longer string.
The second problem is that the characters these functions use are limited to lowercase letters and numbers. You no longer have the uppercase letters and punctuation. That is going to make any string easier to guess.
Your first idea is sometimes the best
For me I'm perfectly happy generating a random string one character at a time. In the future I'll likely generate random strings in much the same way I always have with one small alteration. I'll replace the long list of characters with chr. There's no point typing more than I have to.
Writing some code to produce a fairly random string is incredibly easy. I've easily done it a dozen times or more. Though only because it is easier to re-write it than to find where I put the last one. They generally look something like this:
<?php
$charString = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLOMNOPQRSTUVWXYZ,./<>?;#:@~[]{}-_=+)(*&^%$£"!';
$length = strlen($charString);
$output = '';
for ($a = 0; $a < 16; $a++) {
$output .= $charString{mt_rand(0, $length - 1)};
}
echo $output;
$charString = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLOMNOPQRSTUVWXYZ,./<>?;#:@~[]{}-_=+)(*&^%$£"!';
$length = strlen($charString);
$output = '';
for ($a = 0; $a < 16; $a++) {
$output .= $charString{mt_rand(0, $length - 1)};
}
echo $output;
Running that creates a string something like '4e)+bSuv#kN^"O)f'. Suitably random. Well, pseudo-random.
This isn't the only way to generate a random string. You could take a similar approach but use the chr function instead.
The output is just as good and you don't have to type out every character you want to use. It was only recently, when working on a puzzle posted by Marco Tabini that I considered using chr. This got me thinking about what other options there were.
The uniqid function is one possibility. It does seem to take about twice as long as the first option listed here though. The manual page also contains this gem:
more_entropy
If set to TRUE, uniqid() will add additional entropy (using the combined linear congruential generator) at the end of the return value, which should make the results more unique.
The emphasis is mine.
Other options include the hashing functions. md5 and sha1 would be two options.
There are a couple of problems with uniqid, md5 and sha1 though. Firstly they all return strings of a set length. You would need to use substr to get a shorter string and chain multiple calls together to get a longer string.
The second problem is that the characters these functions use are limited to lowercase letters and numbers. You no longer have the uppercase letters and punctuation. That is going to make any string easier to guess.
Your first idea is sometimes the best
For me I'm perfectly happy generating a random string one character at a time. In the future I'll likely generate random strings in much the same way I always have with one small alteration. I'll replace the long list of characters with chr. There's no point typing more than I have to.
