您的位置:首页 > 编程语言 > PHP开发

php 使用“/dev/urandom”获取随机数

2016-09-22 21:37 330 查看

描述

  首先,说一下伪随机数,伪随机数并不是假随机数,这里的“伪”是有规律的意思,就是计算机产生的伪随机数既是随机的又是有规律的。怎样理解呢?产生的伪随机数有时遵守一定的规律,有时不遵守任何规律;伪随机数有一部分遵守一定的规律;另一部分不遵守任何规律。比如“世上没有两片形状完全相同的树叶”。

  /dev/random和/dev/urandom是Linux系统中提供的随机伪设备,这两个设备的任务,是提供永不为空的随机字节数据流。很多解密程序与安全应用程序(如SSH Keys,SSL Keys等)需要它们提供的随机数据流。

  这两个设备的差异在于:/dev/random的random pool依赖于系统中断,因此在系统的中断数不足时,/dev/random设备会一直封锁,尝试读取的进程就会进入等待状态,直到系统的中断数充分够用, /dev/random设备可以保证数据的随机性。/dev/urandom不依赖系统的中断,也就不会造成进程忙等待,但是数据的随机性也不高。

代码示例

利用mycrpt

/*
* 通过此方法获取随机数,但需要mycrpt支持
*
*/
private function GetURandom2($min = 0, $max = 0x7FFFFFFF)
{/*{{{*/
$diff = $max - $min;
if ($diff < 0 || $diff > 0x7FFFFFFF) {
throw new RuntimeException("Bad range");
}

$bytes = mcrypt_create_iv(4, MCRYPT_DEV_URANDOM);
if ($bytes === false || strlen($bytes) != 4) {
throw new RuntimeException("Unable to get 4 bytes");
}

$ary = unpack("Nint", $bytes);
$val = $ary['int'] & 0x7FFFFFFF;   // 32-bit safe
$fp = (float) $val / 2147483647.0; // convert to [0,1]

return round($fp * $diff) + $min;
}/*}}}*/
}


使用fread读取/dev/urandom文件

/* *
* php 版本 >= 5.3, 通过读取"/dev/urandom"实现产生较好随机数
*
* */
private function GetURandom($min = 0, $max = 0x7FFFFFFF)
{/*{{{*/
$diff = $max - $min;
if ($diff > PHP_INT_MAX) {
throw new RuntimeException('Bad Range');
}

$fh = fopen('/dev/urandom', 'r');
stream_set_read_buffer($fh, PHP_INT_SIZE);
$bytes = fread($fh, PHP_INT_SIZE );
if ($bytes === false || strlen($bytes) != PHP_INT_SIZE ) {
//throw new RuntimeException("nable to get". PHP_INT_SIZE . "bytes");
return 0;
}
fclose($fh);

if (PHP_INT_SIZE == 8) { // 64-bit versions
list($higher, $lower) = array_values(unpack('N2', $bytes));
$value = $higher << 32 | $lower;
}
else { // 32-bit versions
list($value) = array_values(unpack('Nint', $bytes));

}

$val = $value & PHP_INT_MAX;
$fp = (float)$val / PHP_INT_MAX; // convert to [0,1]

return (int)(round($fp * $diff) + $min);
}/*}}}*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  php 随机数