php 获取a-z中随机
This article analyzes problems related to random number generation used for cryptography purposes. PHP 5 does not provide an easy mechanism for generating cryptographically strong random numbers, while PHP 7 solves this by introducing a couple of CSPRNG functions.
本文分析了与用于加密目的的随机数生成有关的问题。 PHP 5没有提供一种简单的机制来生成具有密码强度的随机数,而PHP 7通过引入几个CSPRNG函数来解决此问题。
Quoting Wikipedia, a Cryptographically Secure Pseudorandom Number Generator (CSPRNG) is a pseudo-random number generator (PRNG) with properties that make it suitable for use in cryptography.
引用维基百科 ,加密安全的伪随机数生成器(CSPRNG)是一种伪随机数生成器(PRNG),其属性使其适合在密码学中使用。
A CSPRNG could be mainly useful for:
CSPRNG主要可用于:
Key generation (e.g. generation of complicated keys) 密钥生成(例如,复杂密钥的生成) Creating random passwords for new user accounts 为新用户帐户创建随机密码 Encryption systems 加密系统A central aspect to keeping a high security level is the high quality of randomness.
保持高安全级别的一个主要方面是高质量的随机性。
PHP 7 introduces two new functions that can be used for CSPRNG: random_bytes and random_int.
PHP 7引入了两个可用于CSPRNG的新函数: random_bytes和random_int 。
The random_bytes function returns a string and accepts as input an int representing the length in bytes to be returned.
random_bytes函数返回一个string并接受一个表示要返回的字节长度的int作为输入。
Example:
例:
$bytes = random_bytes('10'); var_dump(bin2hex($bytes)); //possible ouput: string(20) "7dfab0af960d359388e6"The random_int function returns an integer number within the given range. Example:
random_int函数返回给定范围内的整数。 例:
var_dump(random_int(1, 100)); //possible output: 27The sources of randomness of the above functions are different depending on the environment:
上述功能的随机性源因环境而异:
On Windows, CryptGenRandom() will always be used.
在Windows上,将始终使用CryptGenRandom() 。
On other platforms, arc4random_buf() will be used if it is available (true on BSD derivatives or systems with libbsd).
在其他平台上,如果可用,将使用arc4random_buf() (在BSD派生类或具有libbsd的系统上为true)。
Failing the above, a Linux getrandom(2) syscall will be used.
如果失败,将使用Linux getrandom(2) syscall。
If all else fails /dev/urandom will be used as the final fallback. 如果其他所有方法都失败,则将/ dev / urandom用作最终的后备。If none of the above sources are available, then an Error will be thrown.
如果以上来源均不可用,则将引发Error 。
A good random number generation system assures the right “quality” of generations. To check this quality, a battery of statistical tests is often performed. Without delving into complex statistical topics, comparing a known behavior with the result of a number generator can help in a quality evaluation.
一个好的随机数生成系统可以确保正确的生成“质量”。 为了检查该质量,经常执行一系列统计测试。 在不研究复杂的统计主题的情况下,将已知行为与数字生成器的结果进行比较可以帮助进行质量评估。
One easy test is the dice game. Assuming the odds of rolling a six with one die are one in six, if I roll three dice at the same time 100 times, the expected values for 0, 1, 2, and 3 sixes are roughly:
一个简单的测试是骰子游戏。 假设用一个骰子掷出六个骰子的几率是六分之一,如果我同时掷三个骰子100次,则0、1、2和3个骰子的期望值大致为:
0 sixes = 57.9 times 0秒= 57.9倍 1 sixes = 34.7 times 1个6 = 34.7倍 2 sixes = 6.9 times 2个6 = 6.9倍 3 sixes = 0.5 times 3个6 = 0.5次Here is the code to reproduce the dice roll 1.000.000 times:
这是将骰子掷出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);Testing the code above with PHP7 random_int and the simple rand function might produce:
使用PHP7 random_int和简单的rand函数测试以上代码可能会产生:
Sixesexpectedrandom_intrand0579000579430578179134700034692734762026900068985695863500046584615 Sixes 预期 random_int rand 0 579000 579430 578179 1个 347000 346927 347620 2 69000 68985 69586 3 5000 4658 4615To see a better comparison between rand and random_int we can plot the results in a graph applying a formula to increase the differences between values: php result - expected result / sqrt(expected).
为了更好地比较rand和random_int我们可以将结果绘制在图形中,并应用公式来增加值之间的差异: php result - expected result / sqrt(expected) 。
The resulting graph will be:
结果图将是:
(values close to zero are better)
(接近零的值更好)
Even if the three sixes combination doesn’t perform well, and the test is too easy for a real application we can clearly see that random_int performs better than rand. Furthermore, the security of an application is increased by the absence of predictable, repeatable behaviors in the random number generator adopted.
即使三个6个组合的效果不佳,并且测试对于实际应用来说太简单了,我们也可以清楚地看到random_int性能优于rand 。 此外,由于在采用的随机数生成器中没有可预测的,可重复的行为,因此提高了应用程序的安全性。
By default, PHP 5 does not provide any strong pseudo-random number generators. In reality, there are some options like openssl_random_pseudo_bytes(), mcrypt_create_iv() or directly use the /dev/random or /dev/urandom devices with fread(). There are also packages like RandomLib or libsodium.
默认情况下,PHP 5不提供任何强大的伪随机数生成器。 实际上,有一些选项,例如openssl_random_pseudo_bytes() , mcrypt_create_iv()或直接将/dev/random或/dev/urandom设备与fread() 。 也有像RandomLib或libsodium这样的软件包。
If you want to start using a good random number generator and at the same time be PHP 7-ready you can use the Paragon Initiative Enterprises random_compat library. The random_compat library allows the use of random_bytes() and random_int() in your PHP 5.x project.
如果您想开始使用一个好的随机数生成器,并且同时准备使用PHP 7,则可以使用Paragon Initiative Enterprises的random_compat库。 random_compat库允许在PHP 5.x项目中使用random_bytes()和random_int() 。
The library can be installed via Composer:
该库可以通过Composer安装:
composer require paragonie/random_compat require 'vendor/autoload.php'; $string = random_bytes(32); var_dump(bin2hex($string)); // string(64) "8757a27ce421b3b9363b7825104f8bc8cf27c4c3036573e5f0d4a91ad2aaec6f" $int = random_int(0,255); var_dump($int); // int(81)The random_compat library uses a different preference order compared to the PHP 7 one:
与PHP 7相比, random_compat库使用不同的首选项顺序:
fread() /dev/urandom if available
fread() /dev/urandom如果可用)
mcrypt_create_iv($bytes, MCRYPT_CREATE_IV)
mcrypt_create_iv($bytes, MCRYPT_CREATE_IV)
COM('CAPICOM.Utilities.1')->GetRandom()
COM('CAPICOM.Utilities.1')->GetRandom()
openssl_random_pseudo_bytes()
openssl_random_pseudo_bytes()
For more information about why this order has been used, I suggest reading the documentation.
有关为何使用此命令的更多信息,建议阅读文档 。
A simple use of the library to generate a password can be:
使用该库生成密码的简单用法可以是:
$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: 7rgG8GHuYou should always apply a cryptographically secure pseudo-random number generator, and the random_compat lib provides a good implementation for this.
您应该始终应用加密安全的伪随机数生成器,并且random_compat lib random_compat提供了一个很好的实现。
If you want to use a reliable random data source, as you saw in the article, the suggestion is to start as soon as possible with random_int and random_bytes.
如您在文章中所见,如果您想使用可靠的随机数据源,建议尽快从random_int和random_bytes 。
Questions or comments? Leave them below!
有疑问或意见吗? 把它们留在下面!
Many thanks to the following peer reviewers for their help with this article!
非常感谢以下同行审稿人对本文的帮助!
Scott Arciszewski
斯科特·阿西塞夫斯基
翻译自: https://www.sitepoint.com/randomness-php-feel-lucky/
php 获取a-z中随机
相关资源:jdk-8u281-windows-x64.exe