public static function randomString($len = null, $chars = null, $cb = null, $pri = 0, $hang = false)
{
if ($len === null) {
$len = 64;
}
if ($chars === null) {
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-.';
}
if ($cb === null) {
Daemon::log('[CODE WARN] \\PHPDaemon\\Utils\\Crypt::randomString: non-callback way is not secure.' . ' Please rewrite your code with callback function in third argument' . PHP_EOL . Debug::backtrace());
$r = '';
$m = mb_orig_strlen($chars) - 1;
for ($i = 0; $i < $len; ++$i) {
$r .= $chars[mt_rand(0, $m)];
}
return $r;
}
$charsLen = mb_orig_strlen($chars);
$mask = static::getMinimalBitMask($charsLen - 1);
$iterLimit = max($len, $len * 64);
static::randomInts(2 * $len, function ($ints) use($cb, $chars, $charsLen, $len, $mask, &$iterLimit) {
if ($ints === false) {
$cb(false);
return;
}
$r = '';
for ($i = 0, $s = sizeof($ints); $i < $s; ++$i) {
// This is wasteful, but RNGs are fast and doing otherwise adds complexity and bias
$c = $ints[$i] & $mask;
// Only use the random number if it is in range, otherwise try another (next iteration)
if ($c < $charsLen) {
$r .= static::stringIdx($chars, $c);
}
// Guarantee termination
if (--$iterLimit <= 0) {
return false;
}
}
$d = $len - mb_orig_strlen($r);
if ($d > 0) {
static::randomString($d, $chars, function ($r2) use($r, $cb) {
$cb($r . $r2);
});
return;
}
$cb($r);
}, $pri, $hang);
}