Completed
Push — master ( 1aab2c...6ed5f9 )
by Michael
02:53
created

Random::bytes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
3
/**
4
 * Random.php
5
 * 
6
 * PHP version 7
7
 * 
8
 * @category Dcrypt
9
 * @package  Dcrypt
10
 * @author   Michael Meyer (mmeyer2k) <[email protected]>
11
 * @license  http://opensource.org/licenses/MIT The MIT License (MIT)
12
 * @link     https://github.com/mmeyer2k/dcrypt
13
 * @link     https://apigen.ci/github/mmeyer2k/dcrypt
14
 */
15
16
namespace Dcrypt;
17
18
/**
19
 * Fail-safe wrapper for mcrypt_create_iv (preferably) and
20
 * openssl_random_pseudo_bytes (fallback).
21
 *
22
 * @category Dcrypt
23
 * @package  Dcrypt
24
 * @author   Michael Meyer (mmeyer2k) <[email protected]>
25
 * @license  http://opensource.org/licenses/MIT The MIT License (MIT)
26
 * @link     https://github.com/mmeyer2k/dcrypt
27
 * @link     https://apigen.ci/github/mmeyer2k/dcrypt/class-Dcrypt.Random.html
28
 */
29
final class Random
30
{
31
    /**
32
     * Return securely generated random bytes.
33
     * 
34
     * @param int  $bytes  Number of bytes to get
35
     * 
36
     * @return string
37
     */
38 19
    public static function bytes(int $bytes): string
39
    {        
40 19
        return \random_bytes($bytes);
41
    }    
42 19
43
    /**
44
     * Deterministic seeded array shuffle function. Does not keep keys.
45
     *
46 19
     * @param array  $array  Array to shuffle
47
     * @param string $seed   Seed to use 
48
     * @param bool   $secure Whether to use secure RNG in PHP 7.1+. Use false to fall back to broken version for BC.
49
     *
50
     * @return array
51
     */
52
    public static function shuffle(array $array, string $seed, bool $secure = true): array
53
    {
54
        $count = \count($array);
55
56 19
        $range = \range(0, $count - 1);
57
58 19
        // Hash the seed and extract bytes to make integer with
59
        $seed = Str::substr(\hash('sha256', $seed, true), 0, PHP_INT_SIZE);
60 19
61 19
        // Convert bytes to an int
62
        $seed = \unpack("L", $seed);
63
64
        if (\version_compare(PHP_VERSION, '7.1.0') >= 0 && $secure === false) {
65
            // Handle PHP 7.1+ calls requiring the old implementation which has broken implementation
66
            \mt_srand($seed[1], MT_RAND_PHP);
67
        } else {
68
            \mt_srand($seed[1]);
69
        }
70
71
        // Swap array values randomly
72
        foreach ($range as $a) {
73
            $b = \mt_rand(0, $count - 1);
74
75
            $v = $array[$a];
76
77
            $array[$a] = $array[$b];
78
79
            $array[$b] = $v;
80
        }
81
82
        return $array;
83
    }
84
}
85