Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
random.php
1<?php
2
4
5class Random
6{
8 // ToDo: In future versions (PHP >= 5.6.0) use shift to the left instead this s**t
9 const ALPHABET_NUM = 1;
13 const ALPHABET_ALL = 15;
14
15 protected static $alphabet = array(
16 self::ALPHABET_NUM => '0123456789',
17 self::ALPHABET_ALPHALOWER => 'abcdefghijklmnopqrstuvwxyz',
18 self::ALPHABET_ALPHAUPPER => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
19 self::ALPHABET_SPECIAL => ',.#!*%$:-^@{}[]()_+=<>?&;'
20 );
21
30 public static function getInt($min = 0, $max = \PHP_INT_MAX)
31 {
32 if ($min > $max)
33 {
34 throw new \Bitrix\Main\ArgumentException(
35 'The min parameter must be lower than max parameter'
36 );
37 }
38
39 $range = $max - $min;
40
41 if ($range == 0)
42 return $max;
43
44 if ($range > \PHP_INT_MAX || is_float($range))
45 {
46 throw new \Bitrix\Main\SystemException(
47 'The supplied range is too great'
48 );
49 }
50
51 $bits = static::countBits($range) + 1;
52 $length = (int) max(ceil($bits / 8), 1);
53 $filter = pow(2, $bits) - 1;
54 if ($filter >= \PHP_INT_MAX)
55 $filter = \PHP_INT_MAX;
56 else
57 $filter = (int) $filter;
58
59 do
60 {
61 $rnd = hexdec(bin2hex(self::getBytes($length)));
62 $rnd = $rnd & $filter;
63 }
64 while ($rnd > $range);
65
66 return ($min + $rnd);
67 }
68
76 public static function getString($length, $caseSensitive = false)
77 {
78 $alphabet = self::ALPHABET_NUM | self::ALPHABET_ALPHALOWER;
79 if ($caseSensitive)
80 {
82 }
83
84 return static::getStringByAlphabet($length, $alphabet);
85 }
86
94 public static function getStringByAlphabet($length, $alphabet, $requireAll = false)
95 {
96 $charsetList = static::getCharsetsforAlphabet($alphabet);
97
98 if($requireAll && count($charsetList) > 1)
99 {
100 return static::getStringByArray($length, $charsetList);
101 }
102 else
103 {
104 return static::getStringByCharsets($length, implode("", $charsetList));
105 }
106 }
107
115 public static function getStringByCharsets($length, $charsetList)
116 {
117 $charsetVariants = strlen($charsetList);
118 $randomSequence = static::getBytes($length);
119
120 $result = '';
121 for ($i = 0; $i < $length; $i++)
122 {
123 $randomNumber = ord($randomSequence[$i]);
124 $result .= $charsetList[$randomNumber % $charsetVariants];
125 }
126 return $result;
127 }
128
135 public static function getStringByArray(int $length, array $charsetList): string
136 {
137 $count = count($charsetList);
138
139 // take strlen() out of the cycle
140 $charsets = [];
141 foreach ($charsetList as $charset)
142 {
143 $charsets[] = [$charset, strlen($charset)];
144 }
145
146 $randomSequence = static::getBytes($length);
147
148 $result = '';
149 for ($i = 0; $i < $length; $i += $count)
150 {
151 shuffle($charsets);
152
153 for ($j = 0; $j < $count; $j++)
154 {
155 $randomNumber = ord($randomSequence[$i + $j]);
156
157 $charset = $charsets[$j][0];
158 $charsetVariants = $charsets[$j][1];
159 $result .= $charset[$randomNumber % $charsetVariants];
160
161 if (($i + $j + 1) == $length)
162 {
163 break 2;
164 }
165 }
166 }
167
168 return $result;
169 }
170
177 public static function getBytes($length)
178 {
179 $backup = null;
180
181 if ($length <= 0)
182 {
183 $length = 1;
184 }
185
186 $bytes = openssl_random_pseudo_bytes($length, $strong);
187 if ($bytes && strlen($bytes) >= $length)
188 {
189 if ($strong)
190 {
191 return substr($bytes, 0, $length);
192 }
193 $backup = $bytes;
194 }
195
196 if (file_exists('/dev/urandom'))
197 {
198 if ($file = @fopen('/dev/urandom', 'rb'))
199 {
200 $bytes = @fread($file, $length + 1);
201 @fclose($file);
202 if ($bytes && strlen($bytes) >= $length)
203 {
204 return substr($bytes, 0, $length);
205 }
206 }
207 }
208
209 if ($backup && strlen($backup) >= $length)
210 {
211 return substr($backup, 0, $length);
212 }
213
214 $bytes = '';
215 while (strlen($bytes) < $length)
216 {
217 $bytes .= static::getPseudoRandomBlock();
218 }
219
220 return substr($bytes, 0, $length);
221 }
222
228 protected static function getPseudoRandomBlock()
229 {
230 $bytes = openssl_random_pseudo_bytes(static::RANDOM_BLOCK_LENGTH);
231 if ($bytes && strlen($bytes) >= static::RANDOM_BLOCK_LENGTH)
232 {
233 return substr($bytes, 0, static::RANDOM_BLOCK_LENGTH);
234 }
235
236 $bytes = '';
237 for ($i=0; $i < static::RANDOM_BLOCK_LENGTH; $i++)
238 {
239 $bytes .= pack('S', mt_rand(0,0xffff));
240 }
241
242 return hash('sha512', $bytes, true);
243 }
244
263 protected static function getCharsetsForAlphabet($alphabet)
264 {
265 $result = [];
266 foreach (static::$alphabet as $mask => $value)
267 {
268 if ($alphabet & $mask)
269 {
270 $result[] = $value;
271 }
272 }
273
274 return $result;
275 }
276
283 protected static function countBits($value)
284 {
285 $result = 0;
286 while ($value >>= 1)
287 $result++;
288
289 return $result;
290 }
291}
static getString($length, $caseSensitive=false)
Definition random.php:76
static getCharsetsForAlphabet($alphabet)
Definition random.php:263
static getStringByArray(int $length, array $charsetList)
Definition random.php:135
static countBits($value)
Definition random.php:283
static getStringByAlphabet($length, $alphabet, $requireAll=false)
Definition random.php:94
static getStringByCharsets($length, $charsetList)
Definition random.php:115
static getBytes($length)
Definition random.php:177
static getInt($min=0, $max=\PHP_INT_MAX)
Definition random.php:30