Generate a random string of non-ambiguous numbers and letters.
I needed to generate a unique code, suitable for URLs and somewhat short so it doesn’t scare the user.
Doing md5(microtime()) is nice but it is 32 chars long. I could use base64, but it contains weird characters like “/” and “=”.
So how do I restrain the encoding to alphanumeric ? I found the inspiration from Ross Duggan and I added a random function. He also removes a couple ambiguous chars, which I think is a nice touch.
The choice of random could be discussed but the idea is there.
UPDATE: As suggested by a friend, it is simpler and a better use of the range of available entropy to generate each character separately. You can see the old version in the Gist.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php
// CodeGenerator.php
class CodeGenerator
{
private static $alphabet = '23456789abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ';
private static $max_offset = 55;
/**
* Generate a random character of non-ambiguous number or letter.
* @return string the character
*/
public static function randomChar()
{
$index = mt_rand(0, self::$max_offset);
return self::$alphabet[$index];
}
/**
* Generate a random string of non-ambiguous numbers and letters.
* @param $length Size of generated string
* @return string
* @throws InvalidArgumentException
*/
public static function generate($length = 16)
{
if ($length < 1) {
throw new InvalidArgumentException(__METHOD__ . ' expects a $length argument of at least 1, input was: ' . $length);
}
$random = '';
for ($i=0; $i < $length; $i++) {
$random .= self::randomChar();
}
return $random;
}
}