Completed
Push — master ( 7a49c4...a09f64 )
by Peter
03:47
created

Base64UID::random()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 32
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 6.2373

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 32
ccs 13
cts 16
cp 0.8125
rs 8.439
cc 6
eloc 17
nc 6
nop 2
crap 6.2373
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 1
        }
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
     * @throws \Exception
42
     *
43
     * @param int $min
44
     * @param int $max
45
     *
46
     * @return int|null
47
     */
48 1
    private static function random($min, $max)
49
    {
50 1
        if (function_exists('random_int')) {
51
            return random_int($min, $max);
52
        }
53
54
        // @codeCoverageIgnoreStart
55
        if (!function_exists('mcrypt_create_iv')) {
56
            throw new \Exception('mcrypt must be loaded for random_int to work');
57
        }
58
        // @codeCoverageIgnoreEnd
59
60 1
        $range = $counter = $max - $min;
61 1
        $bits = 1;
62
63 1
        while ($counter >>= 1) {
64 1
            ++$bits;
65 1
        }
66
67 1
        $bytes = (int) max(ceil($bits / 8), 1);
68 1
        $bitmask = pow(2, $bits) - 1;
69
70 1
        if ($bitmask >= PHP_INT_MAX) {
71
            $bitmask = PHP_INT_MAX;
72
        }
73
74
        do {
75 1
            $result = hexdec(bin2hex(mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM))) & $bitmask;
76 1
        } while ($result > $range);
77
78 1
        return $result + $min;
79
    }
80
}
81