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