1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Nette\Utils;
9:
10: use Nette;
11:
12:
13: 14: 15:
16: class Random
17: {
18: use Nette\StaticClass;
19:
20: 21: 22: 23: 24: 25:
26: public static function generate($length = 10, $charlist = '0-9a-z')
27: {
28: $charlist = count_chars(preg_replace_callback('#.-.#', function (array $m) {
29: return implode('', range($m[0][0], $m[0][2]));
30: }, $charlist), 3);
31: $chLen = strlen($charlist);
32:
33: if ($length < 1) {
34: throw new Nette\InvalidArgumentException('Length must be greater than zero.');
35: } elseif ($chLen < 2) {
36: throw new Nette\InvalidArgumentException('Character list must contain as least two chars.');
37: }
38:
39: $res = '';
40: if (PHP_VERSION_ID >= 70000) {
41: for ($i = 0; $i < $length; $i++) {
42: $res .= $charlist[random_int(0, $chLen - 1)];
43: }
44: return $res;
45: }
46:
47: $bytes = '';
48: if (function_exists('openssl_random_pseudo_bytes')) {
49: $bytes = (string) openssl_random_pseudo_bytes($length, $secure);
50: if (!$secure) {
51: $bytes = '';
52: }
53: }
54: if (strlen($bytes) < $length && function_exists('mcrypt_create_iv')) {
55: $bytes = (string) mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
56: }
57: if (strlen($bytes) < $length && !defined('PHP_WINDOWS_VERSION_BUILD') && is_readable('/dev/urandom')) {
58: $bytes = (string) file_get_contents('/dev/urandom', false, null, -1, $length);
59: }
60: if (strlen($bytes) < $length) {
61: $rand3 = md5(serialize($_SERVER), true);
62: $charlist = str_shuffle($charlist);
63: for ($i = 0; $i < $length; $i++) {
64: if ($i % 5 === 0) {
65: list($rand1, $rand2) = explode(' ', microtime());
66: $rand1 += lcg_value();
67: }
68: $rand1 *= $chLen;
69: $res .= $charlist[($rand1 + $rand2 + ord($rand3[$i % strlen($rand3)])) % $chLen];
70: $rand1 -= (int) $rand1;
71: }
72: return $res;
73: }
74:
75: for ($i = 0; $i < $length; $i++) {
76: $res .= $charlist[($i + ord($bytes[$i])) % $chLen];
77: }
78: return $res;
79: }
80: }
81: