当前位置:首页 > 日记 > 正文

PHP中的随机性 你觉得自己幸运吗?

PHP中的随机性 你觉得自己幸运吗?

本文分析了生成用于加密的随机数的相关问题。 PHP 5没有提供一种简单的机制来生成密码学上强壮的随机数,但是PHP 7通过引入几个CSPRNG函数来解决了这个问题。

一、什么是CSPRNG

引用维基百科,一个密码学上安全的伪随机数发生器(Cryptographically Secure Pseudorandom Number Generator 缩写CSPRNG)是一个伪随机数生成器(PRNG),其生成的伪随机数适用于密码学算法。

CSPRNG可能主要用于:

  • 密钥生成(例如,生成复杂的密钥)
  • 为新用户产生随机的密码
  • 加密系统

获得高级别安全性的一个关键方面就是高品质的随机性

二、PHP7 中的CSPRNG

PHP 7引入了两个新函数可以用来实现CSPRNG: random_bytes 和 random_int。

random_bytes 函数返回一个字符串,接受一个int型入参代表返回结果的字节数。

例子:

$bytes = random_bytes('10');var_dump(bin2hex($bytes));//possible ouput: string(20) "7dfab0af960d359388e6"

random_int 函数返回一个指定范围内的int型数字。

例子:

var_dump(random_int(1, 100));//possible output: 27

三、后台运行环境

以上函数的随机性不同的取决于环境:

  • 在window上,CryptGenRandom()总是被使用。
  • 在其他平台,arc4random_buf()如果可用会被使用(在BSD系列或者具有libbsd的系统上成立)
  • 以上都不成立的话,一个linux系统调用getrandom(2)会被使用。
  • 如果还不行,/dev/urandom 会被作为最后一个可使用的工具
  • 如果以上都不行,系统会抛出错误

四、一个简单的测试

一个好的随机数生成系统保证合适的产生“质量”。为了检查这个质量, 通常要执行一连串的统计测试。不需要深入研究复杂的统计主题,比较一个已知的行为和数字生成器的结果可以帮助质量评价。

一个简单的测试是骰子游戏。假设掷1个骰子1次得到结果为6的概率是1/6,那么如果我同时掷3个骰子100次,得到的结果粗略如下:

0 个6 = 57.9 次
1 个6 = 34.7次
2 个6 = 6.9次
3 个6 = 0.5次
以下是是实现实现掷骰子1,000,000次的代码:

$times = 1000000;$result = [];for ($i=0; $i<$times; $i++){  $dieRoll = array(6 => 0); //initializes just the six counting to zero  $dieRoll[roll()] += 1; //first die  $dieRoll[roll()] += 1; //second die  $dieRoll[roll()] += 1; //third die  $result[$dieRoll[6]] += 1; //counts the sixes}function roll(){  return random_int(1,6);}var_dump($result);

用PHP7 的 random_int 和简单的 rand 函数可能得到如下结果

如果先看到rand 和 random_int 更好的比较我们可以应用一个公式把结果画在图上。公式是:(php结果-期待的结果)/期待结果的0.5次方。

结果图如下:

(接近0的值更好)

尽管3个6的结果表现不好,并且这个测试对实际应用来说太过简单我们仍可以看出 random_int 表现优于 rand.

进一步,我们的应用的安全级别由于不可预测性和随机数发生器的可重复行为而得到提升。

PHP5 呢

缺省情况下,PHP5 不提供强壮的随机数发生器。实际上,还是有选择的比如 openssl_random_pseudo_bytes(), mcrypt_create_iv() 或者直接使用fread()函数来使用 /dev/random 或 /dev/urandom 设备。也有一些包比如 RandomLib 或 libsodium.

如果你想要开始使用一个更好的随机数发生器并且同时准备好使用PHP7,你可以使用Paragon Initiative Enterprises random_compat 库。 random_compat 库允许你在 PHP 5.x project.使用 random_bytes() and random_int()

这个库可以通过Composer安装:

composer require paragonie/random_compatrequire 'vendor/autoload.php';$string = random_bytes(32);var_dump(bin2hex($string));// string(64) "8757a27ce421b3b9363b7825104f8bc8cf27c4c3036573e5f0d4a91ad2aaec6f"$int = random_int(0,255);var_dump($int);// int(81)

random_compat 库和PHP7使用不同的顺序:

fread() /dev/urandom if availablemcrypt_create_iv($bytes, MCRYPT_CREATE_IV)COM('CAPICOM.Utilities.1')->GetRandom()openssl_random_pseudo_bytes()

这个库的一个简单应用用来产生密码:

$passwordChar = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';$passwordLength = 8;$max = strlen($passwordChar) - 1;$password = '';for ($i = 0; $i < $passwordLength; ++$i) {  $password .= $passwordChar[random_int(0, $max)];}echo $password;//possible output: 7rgG8GHu

总结

你总是应该使用一个密码学上安全的伪随机数生成器,random_compat 库提供了一种好的实现。

如果你想要使用可靠的随机数据源,如你在本文所见,建议尽快使用 random_int 和 random_bytes。

以上就是关于php随机性的相关内容,希望对大家的学习有所帮助。

相关文章

wps如何做考勤表图文教程

wps如何做考勤表图文教程

方法,图文教程,如何做,考勤表,电脑软件,  wps是金山软件公司的一种办公软件,对日常办公起到了重要作用,那么大家对它的一些功能又有多少了解呢?在wps中制作考勤表大家都知道怎么做?对于刚从其它版本转型过来的应该就不会太懂吧,没关系下面小…

如何删除Excel2007单元格中的超链

如何删除Excel2007单元格中的超链

格中,单元,删除,超链接,电脑软件,  我们都知道在Excel单元格中直接输入网站地址的话,会自动变成超链接形式,也就是蓝色的。直接点击,就会跳转到相应的界面,如何删除这些超链接呢?以下是小编为您带来的关于删除Excel2007单元格中的超链接,希望…

浅谈vue-router2路由参数注意的问

浅谈vue-router2路由参数注意的问

参数,路由,浅谈,电脑软件,vue,1、vue 路由 如果传递 params 定义路由的时候是/路由名称:id 获取的时候this.$route.params.id最后形如/路由名称/路由参数传参的时候params:{ str1:str1, str2:str2 }2、如果传递query ?id=str.... 定义路由的…

php显示页码分页类的封装

php显示页码分页类的封装

分页类,封装,显示,页码,电脑软件,本文实例为大家分享了php封装显示页码的分页类,供大家参考,具体内容如下一、代码conn.php<?php class Mysql{ public function __construct(){ $this->connect(); } public function connect(){ …

ps制作一只贱贱的doger表情教程

ps制作一只贱贱的doger表情教程

教程,一只,表情,电脑软件,ps,ps制作一只贱贱的doger表情,教程主要分为前期准备、背景制作、头部和耳朵的绘制、眼睛、鼻子和嘴的绘制,然后添加一些阴影,最后这只贱贱的doge,就完成了。那么,让我们开始练习吧!效果图:主要过程:12 3 4 5 阅读全文1 2…

AngularJS中控制器函数的定义与使

AngularJS中控制器函数的定义与使

控制器,函数,示例,使用方法,定义,本文实例讲述了AngularJS中控制器函数的定义与使用方法。分享给大家供大家参考,具体如下:HTML正文:<body ng-app="myApp" ng-controller="myCtrl"><h2>AngularJS函数绑定</h2><textarea ng-model="messa…

jQuery瀑布流的简单实现代码

jQuery瀑布流的简单实现代码

瀑布流,简单实现,代码,电脑软件,jQuery,简单版的Jquery实现图片瀑布流思路,供大家参考,具体内容如下注意:本篇文章基于知道每张图片的实际尺寸的情况下特点:列数自适应,图片宽度固定已知BUG:像本案例中的刚好5张图片循环显示且只有5列的情况…

利用Chrome DevTools直接调试Node.

利用Chrome DevTools直接调试Node.

方法,并行,调试,详解,电脑软件,前提Node.js 6.3+, 这个可上Node.js官网自行下载;Chrome 55+. 如果您本地的chrome升级到最新版后还是<55, 可以从此处下载:Chrome Canary,亲测可行。配置就目前来说,在浏览器端并行调试JavaScript与Node.js还属于…

js控制按钮,防止频繁点击响应的实

js控制按钮,防止频繁点击响应的实

控制,响应,频繁,实例,按钮,为了防止频繁点击按钮,可以采用一个策略,点击一次后让按钮灰掉,暂时不可以用,一段时间后再可以用,伪代码如下:var clicktag = 0; $('.a_cc').click(function () { if (clicktag == 0) { clickta…

解决局域网不能互相访问之全攻略

解决局域网不能互相访问之全攻略

局域网,全攻略,电脑软件,一般都是简单的设置和物理上的原因,其中XP之间不能互相访问是最近频繁遇到的问题。这篇文章就是来解决这些问题.分两个部分 一: 设置 现在,已经有许多人在使用Win2000和WinXP来联网,但在具体使用中有许多网友反映在Win…

wps文字如何同时打开两个文档wps文

wps文字如何同时打开两个文档wps文

文档,文字,方法,两个,电脑软件,  我们在办公时有时需要对两份文档进行对比,下面小编介绍下wps文字进行文档比较的方法。希望对你有帮助!wps文字同时打开两个文档的方法打开需要进行比较的文档。wps文字同时打开两个文档的方法图1  选择视…

详解vue嵌套路由-query传递参数

详解vue嵌套路由-query传递参数

嵌套,传递参数,路由,详解,电脑软件,在嵌套路由中我们经常会遇到父路由向子路由里面传递参数,传递参数有两种方法,通过 query 或者 paramsindex.html<div id="app"> <!-- router-view 路由出口, 路由匹配到的组件将渲染在这里 --> <rout…