1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Copyright © 2017 Toan Nguyen. All rights reserved. |
4
|
|
|
* |
5
|
|
|
* For the full copyright and license information, please view the LICENSE |
6
|
|
|
* file that was distributed with this source code. |
7
|
|
|
*/ |
8
|
|
|
|
9
|
|
|
namespace Gojira\Framework\Math; |
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* Random data generator |
13
|
|
|
* |
14
|
|
|
* @api |
15
|
|
|
*/ |
16
|
|
|
class Random |
17
|
|
|
{ |
18
|
|
|
/**#@+ |
19
|
|
|
* Frequently used character classes |
20
|
|
|
*/ |
21
|
|
|
const CHARS_LOWERS = 'abcdefghijklmnopqrstuvwxyz'; |
22
|
|
|
|
23
|
|
|
const CHARS_UPPERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; |
24
|
|
|
|
25
|
|
|
const CHARS_DIGITS = '0123456789'; |
26
|
|
|
|
27
|
|
|
/**#@-*/ |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* Get random string |
31
|
|
|
* |
32
|
|
|
* @param int $length |
33
|
|
|
* @param null|string $chars |
34
|
|
|
* |
35
|
|
|
* @return string |
36
|
|
|
* @throws \Gojira\Framework\Exception\LocalizedException |
37
|
|
|
*/ |
38
|
|
|
public function getRandomString($length, $chars = null) |
39
|
|
|
{ |
40
|
|
|
$str = ''; |
41
|
|
|
if (null === $chars) { |
42
|
|
|
$chars = self::CHARS_LOWERS . self::CHARS_UPPERS . self::CHARS_DIGITS; |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
if (function_exists('openssl_random_pseudo_bytes')) { |
46
|
|
|
// use openssl lib if it is installed |
47
|
|
View Code Duplication |
for ($i = 0, $lc = strlen($chars) - 1; $i < $length; $i++) { |
|
|
|
|
48
|
|
|
$bytes = openssl_random_pseudo_bytes(PHP_INT_SIZE); |
49
|
|
|
$hex = bin2hex($bytes); // hex() doubles the length of the string |
50
|
|
|
$rand = abs(hexdec($hex) % $lc); // random integer from 0 to $lc |
51
|
|
|
$str .= $chars[$rand]; // random character in $chars |
52
|
|
|
} |
53
|
|
|
} elseif ($fp = fopen('/dev/urandom', 'rb')) { |
54
|
|
|
// attempt to use /dev/urandom if it exists but openssl isn't available |
55
|
|
View Code Duplication |
for ($i = 0, $lc = strlen($chars) - 1; $i < $length; $i++) { |
|
|
|
|
56
|
|
|
$bytes = fread($fp, PHP_INT_SIZE); |
57
|
|
|
$hex = bin2hex($bytes); // hex() doubles the length of the string |
58
|
|
|
$rand = abs(hexdec($hex) % $lc); // random integer from 0 to $lc |
59
|
|
|
$str .= $chars[$rand]; // random character in $chars |
60
|
|
|
} |
61
|
|
|
fclose($fp); |
62
|
|
|
} else { |
63
|
|
|
throw new \Gojira\Framework\Exception\LocalizedException( |
64
|
|
|
new \Gojira\Framework\Phrase("Please make sure you have 'openssl' extension installed") |
65
|
|
|
); |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
return $str; |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* Return a random number in the specified range |
73
|
|
|
* |
74
|
|
|
* @param $min [optional] |
75
|
|
|
* @param $max [optional] |
76
|
|
|
* |
77
|
|
|
* @return int A random integer value between min (or 0) and max |
78
|
|
|
* @throws \Gojira\Framework\Exception\LocalizedException |
79
|
|
|
*/ |
80
|
|
|
public static function getRandomNumber($min = 0, $max = null) |
81
|
|
|
{ |
82
|
|
|
if (null === $max) { |
83
|
|
|
$max = mt_getrandmax(); |
84
|
|
|
} |
85
|
|
|
$range = $max - $min + 1; |
86
|
|
|
$offset = 0; |
|
|
|
|
87
|
|
|
|
88
|
|
|
if (function_exists('openssl_random_pseudo_bytes')) { |
89
|
|
|
// use openssl lib if it is installed |
90
|
|
|
$bytes = openssl_random_pseudo_bytes(PHP_INT_SIZE); |
91
|
|
|
$hex = bin2hex($bytes); // hex() doubles the length of the string |
92
|
|
|
$offset = abs(hexdec($hex) % $range); // random integer from 0 to $range |
93
|
|
|
} elseif ($fp = fopen('/dev/urandom', 'rb')) { |
94
|
|
|
// attempt to use /dev/urandom if it exists but openssl isn't available |
95
|
|
|
$bytes = fread($fp, PHP_INT_SIZE); |
96
|
|
|
$hex = bin2hex($bytes); // hex() doubles the length of the string |
97
|
|
|
$offset = abs(hexdec($hex) % $range); // random integer from 0 to $range |
98
|
|
|
fclose($fp); |
99
|
|
|
} else { |
100
|
|
|
throw new \Gojira\Framework\Exception\LocalizedException( |
101
|
|
|
new \Gojira\Framework\Phrase("Please make sure you have 'openssl' extension installed") |
102
|
|
|
); |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
return $min + $offset; // random integer from $min to $max |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
/** |
109
|
|
|
* Generate a hash from unique ID |
110
|
|
|
* |
111
|
|
|
* @param string $prefix |
112
|
|
|
* |
113
|
|
|
* @return string |
114
|
|
|
*/ |
115
|
|
|
public function getUniqueHash($prefix = '') |
116
|
|
|
{ |
117
|
|
|
return $prefix . md5(uniqid(microtime() . self::getRandomNumber(), true)); |
118
|
|
|
} |
119
|
|
|
} |
120
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.