Source of: pass.php (Download Source)
Last Modified: Fri, 16 Feb 2007 13:38:18 UTC

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<?php
/**
 * A simple password generator, that creates passwords the way you specify it.
 * Besides the first param, the password length, you have the option to define
 * the characters that should be used as second param, by creating a
 * 'character range'.
 * 
 * One character range consists of 2 characters (start and end). You can use
 * multiple ranges, by seperating them with ',' or just stick with the default
 * ranges.
 * 
 * Usage examples:
 * 
 * echo pass(16);
 * => 16 characters length, default ranges (upper- and lowercase from A to Z
 *    plus numbers from 0 to 9).
 * 
 * echo pass(10, 'az');
 * => 10 characters length, only lowercase characters.
 * 
 * echo pass(7, '09');
 * => 7 characters length, numbers only.
 * 
 * echo pass(5, 'AZ,09');
 * => 5 characters length, uppercase and numbers.
 * 
 * echo pass(13, 'ad,DG,13');
 * => 13 characters length, only lower case characters from a to d, uppercase
 *    characters from D to G and numbers from 1 to 3.
 * 
 * echo pass(16, 'AN,PZ,19');
 * => Many people have problems to distinguish between 0 and O, so it's a bad
 *    idea to use them in passwords. That's the way to leave them out. Other
 *    chars are hard to distinguish over phonelines, but i guess you got the
 *    idea...
 * 
 * @param  int    $length Password length.
 * @param  string $ranges Optional character ranges, seperated by ','.
 * @return string The password.
 * @author g0a <g0a@g0a.net>
 * 
 **/
function pass($length, $ranges = 'az,AZ,09') {
    // Make sure, we've something to work with.

    strlen($ranges) > 1 or trigger_error('Invalid char range(s)', E_USER_ERROR);
    (int)$length    > 1 or trigger_error('Invalid pass length', E_USER_ERROR);
    // Define static vars.

    static $last_ranges = null;
    static $chars = null;
    // In case of the first call, seed the randomizer.

    if ($chars === null) {
        // First part using microseconds.

        list($usec, $sec) = explode(' ', microtime());
        $seed = (int)$sec + ((int)$usec * 1000000);
        // Second part using some more random information.

        $strlen = strlen($server = implode($_SERVER));
        for ($i = 0; $i < $strlen; $i++) {
            $seed += ord($server{$i});
        }
        // Finally seed it.

        srand($seed);
    }
    // In case of the first call or changed char ranges, build the $chars array.

    if ($chars === null || $ranges !== $last_ranges) {
        foreach (explode(',', $ranges) as $range) {
            $chars = array_merge($chars, range($range{0}, $range{1}));
        }
    }
    // Build the password.

    $pass = '';
    for ($i = 0; $i < $length; $i++) {
        $pass .= $chars[array_rand($chars)];
    }
    // Save ranges to compare at next call.

    $last_ranges = $ranges;
    return $pass;
}
?>