Completed
Push — master ( 62087a...7a49c4 )
by Peter
04:18
created

Base64UID::random()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 30
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 25.3095

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 30
ccs 3
cts 16
cp 0.1875
rs 8.439
cc 6
eloc 17
nc 6
nop 2
crap 25.3095
1
<?php
2
3
/**
4
 * GpsLab component.
5
 *
6
 * @author    Peter Gribanov <[email protected]>
7
 * @copyright Copyright (c) 2011, Peter Gribanov
8
 * @license   http://opensource.org/licenses/MIT
9
 */
10
11
namespace GpsLab\Component\Base64UID;
12
13
class Base64UID
14
{
15
    /**
16
     * @var string
17
     */
18
    private static $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-';
19
20
    /**
21
     * @param int $length
22
     *
23
     * @return string
24
     */
25 1
    public static function generate($length = 10)
26
    {
27 1
        $uid = '';
28 1
        while ($length-- > 0) {
29 1
            $uid .= self::$chars[self::random(0, 63)];
30
        }
31
32 1
        return $uid;
33
    }
34
35
    /**
36
     * Generates cryptographically secure pseudo-random integers.
37
     *
38
     * Follback for PHP < 7.0
39
     *
40
     * @see http://php.net/manual/en/function.random-int.php#119670
41
     *
42
     * @param int $min
43
     * @param int $max
44
     *
45
     * @return int|null
46
     * @throws \Exception
47
     */
48 1
    private static function random($min, $max)
49
    {
50 1
        if (function_exists('random_int')) {
51 1
            return random_int($min, $max);
52
        }
53
54
        if (!function_exists('mcrypt_create_iv')) {
55
            throw new \Exception('mcrypt must be loaded for random_int to work');
56
        }
57
58
        $range = $counter = $max - $min;
59
        $bits = 1;
60
61
        while ($counter >>= 1) {
62
            ++$bits;
63
        }
64
65
        $bytes = (int) max(ceil($bits / 8), 1);
66
        $bitmask = pow(2, $bits) - 1;
67
68
        if ($bitmask >= PHP_INT_MAX) {
69
            $bitmask = PHP_INT_MAX;
70
        }
71
72
        do {
73
            $result = hexdec(bin2hex(mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM))) & $bitmask;
74
        } while ($result > $range);
75
76
        return $result + $min;
77
    }
78
}
79