Completed
Push — master ( d80d04...c9a55e )
by Peter
05:24
created

Base64UID   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 69
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 86.36%

Importance

Changes 5
Bugs 0 Features 1
Metric Value
wmc 8
c 5
b 0
f 1
lcom 1
cbo 0
dl 0
loc 69
ccs 19
cts 22
cp 0.8636
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A generate() 0 9 2
B random() 0 32 6
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
     *
42
     * @throws \Exception
43
     *
44
     * @param int $min
45
     * @param int $max
46
     *
47
     * @return int|null
48
     */
49 1
    private static function random($min, $max)
50
    {
51 1
        if (function_exists('random_int')) {
52
            return random_int($min, $max);
53
        }
54
55
        // @codeCoverageIgnoreStart
56
        if (!function_exists('mcrypt_create_iv')) {
57
            throw new \Exception('mcrypt must be loaded for random_int to work');
58
        }
59
        // @codeCoverageIgnoreEnd
60
61 1
        $range = $counter = $max - $min;
62 1
        $bits = 1;
63
64 1
        while ($counter >>= 1) {
65 1
            ++$bits;
66 1
        }
67
68 1
        $bytes = (int) max(ceil($bits / 8), 1);
69 1
        $bitmask = pow(2, $bits) - 1;
70
71 1
        if ($bitmask >= PHP_INT_MAX) {
72
            $bitmask = PHP_INT_MAX;
73
        }
74
75
        do {
76 1
            $result = hexdec(bin2hex(mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM))) & $bitmask;
77 1
        } while ($result > $range);
78
79 1
        return $result + $min;
80
    }
81
}
82