Passed
Push — main ( 2b8b68...c2075e )
by Anatolyi
05:44
created

Random   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 84
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 9
eloc 24
c 1
b 0
f 1
dl 0
loc 84
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getInteger() 0 3 1
A getBoolean() 0 5 1
A getFloat() 0 9 1
A getBytes() 0 3 1
A getString() 0 27 5
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gambling\Tech;
6
7
use Exception;
8
use Gambling\Tech\Exception\InvalidArgumentException;
9
10
class Random
11
{
12
    /**
13
     * Generate random bytes using different approaches
14
     *
15
     * @param int $length
16
     * @return string
17
     * @throws Exception
18
     */
19
    public static function getBytes(int $length): string
20
    {
21
        return random_bytes($length);
22
    }
23
24
    /**
25
     * @param int $min
26
     * @param int $max
27
     * @return int
28
     * @throws Exception
29
     */
30
    public static function getInteger(int $min, int $max): int
31
    {
32
        return random_int($min, $max);
33
    }
34
35
    /**
36
     * @return bool
37
     * @throws Exception
38
     */
39
    public static function getBoolean(): bool
40
    {
41
        $byte = static::getBytes(1);
42
43
        return (bool)(ord($byte) % 2);
44
    }
45
46
    /**
47
     * @return float
48
     * @throws Exception
49
     */
50
    public static function getFloat(): float
51
    {
52
        $bytes = static::getBytes(7);
53
54
        $bytes[6] = $bytes[6] | chr(0xF0);
55
        $bytes .= chr(63); // exponent bias (1023)
56
        $float = unpack('d', $bytes)[1];
57
58
        return ($float - 1);
59
    }
60
61
    /**
62
     * @param int $length
63
     * @param array $charlist
64
     * @return string
65
     * @throws Exception
66
     */
67
    public static function getString(int $length, array $charlist = [])
68
    {
69
        if ($length < 1) {
70
            throw new InvalidArgumentException('Length should be >= 1');
71
        }
72
73
        // charlist is empty or not provided
74
        if (empty($charlist)) {
75
            $numBytes = (int)ceil($length * 0.75);
76
            $bytes = static::getBytes($numBytes);
77
78
            return mb_substr(rtrim(base64_encode($bytes), '='), 0, $length, '8bit');
79
        }
80
81
        $listLen = mb_strlen($charlist, '8bit');
0 ignored issues
show
Bug introduced by
$charlist of type array is incompatible with the type string expected by parameter $string of mb_strlen(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

81
        $listLen = mb_strlen(/** @scrutinizer ignore-type */ $charlist, '8bit');
Loading history...
82
83
        if ($listLen === 1) {
84
            return str_repeat($charlist, $length);
0 ignored issues
show
Bug introduced by
$charlist of type array is incompatible with the type string expected by parameter $string of str_repeat(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

84
            return str_repeat(/** @scrutinizer ignore-type */ $charlist, $length);
Loading history...
85
        }
86
87
        $result = '';
88
        for ($i = 0; $i < $length; $i++) {
89
            $pos = static::getInteger(0, $listLen - 1);
90
            $result .= $charlist[$pos];
91
        }
92
93
        return $result;
94
    }
95
}
96