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

描述

  首先,说一下伪随机数,伪随机数并不是假随机数,这里的“伪”是有规律的意思,就是计算机产生的伪随机数既是随机的又是有规律的。怎样理解呢?产生的伪随机数有时遵守一定的规律,有时不遵守任何规律;伪随机数有一部分遵守一定的规律;另一部分不遵守任何规律。比如“世上没有两片形状完全相同的树叶”。
  /dev/random和/dev/urandom是Linux系统中提供的随机伪设备,这两个设备的任务,是提供永不为空的随机字节数据流。很多解密程序与安全应用程序(如SSH Keys,SSL Keys等)需要它们提供的随机数据流。
  这两个设备的差异在于:/dev/random的random pool依赖于系统中断,因此在系统的中断数不足时,/dev/random设备会一直封锁,尝试读取的进程就会进入等待状态,直到系统的中断数充分够用, /dev/random设备可以保证数据的随机性。/dev/urandom不依赖系统的中断,也就不会造成进程忙等待,但是数据的随机性也不高。

代码示例

  1. 利用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;
    }/*}}}*/
}
  1. 使用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); 
    }/*}}}*/
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值