Home >Backend Development >PHP Tutorial >PHP's true and false random numbers

PHP's true and false random numbers

*文
*文Original
2017-12-27 10:23:382707browse

This article mainly introduces the detailed explanation of pseudo-random numbers and true random numbers in PHP. This article first explains the related concepts of true random numbers and pseudo-random numbers, and gives a better pseudo-random number than using the mt_rand() function. A piece of example code. I hope to be helpful.

The first thing that needs to be stated is that computers do not generate absolutely random numbers. Computers can only generate "pseudo-random numbers". In fact, absolutely random numbers are just ideal random numbers. No matter how the computer develops, it will not generate a string of absolutely random numbers. Computers can only generate relatively random numbers, that is, pseudo-random numbers.

Pseudo-random numbers are not pseudo-random numbers. The "pseudo" here means regular, that is, the pseudo-random numbers generated by computers are both random and regular. How to understand it? The generated pseudo-random numbers sometimes follow certain rules, and sometimes they do not follow any rules; some of the pseudo-random numbers follow certain rules; the other part does not follow any rules. For example, "There are no two leaves with the same shape in the world." This points to the characteristics of things, that is, randomness, but the leaves of every tree have similar shapes, which is the commonality of things, that is, regularity. From this perspective, you will probably accept the fact that computers can only generate pseudo-random numbers but cannot generate absolutely random numbers.

First, let’s understand the concepts of true random numbers and pseudo-random numbers.

True random number generators: English: true random number generators, abbreviated as: TRNGs, are random numbers generated by unpredictable physical methods.

Pseudo-random number generators: English: pseudo-random number generators, abbreviated as: PRNGs, are generated by computers using certain algorithms.

Compare the pictures of random numbers generated by the two methods.

Random.org (uses atmospheric noise to generate random numbers, and atmospheric noise is generated by thunderstorms in the air) Random bitmap generated:

Random pictures generated by the rand() function of PHP under Windows:

Obviously, the pictures generated by the latter pseudo-random number generator have such obvious stripes.

The code that uses PHP's rand random function to generate this picture is:

//需要开启gd库
header("Content-type: image/png");
$im = imagecreatetruecolor(512, 512)
or die("Cannot Initialize new GD image stream");
$white = imagecolorallocate($im, 255, 255, 255);
for ($y=0; $y<512; $y++) {
for ($x=0; $x<512; $x++) {
if (rand(0,1) === 1) {
imagesetpixel($im, $x, $y, $white);
}
}
}
imagepng($im);
imagedestroy($im);


In fact, not all pseudo-random number generators (PRNGs) are so bad. , it just happens that the rand() function of PHP under Windows is like this. If the same code is tested under Linux, the resulting picture will not show obvious stripes. Under Windows, if the mt_rand() function is used instead of the rand() function, the effect will be much better. This is because mt_rand() uses the Mersenne Twister algorithm to generate random numbers. The PHP documentation also says: mt_rand() can generate random values ​​​​on average four times faster than the rand() provided by libc.

In addition, the Linux kernel (1.3.30 and above) includes a random number generator /dev/random, which is sufficient for many security purposes.

The following is an introduction to the principles of Linux’s random number generator:

The Linux operating system provides libraries that are inherently random (or at least have components with strong randomness) data. This data usually comes from the device driver. For example, a keyboard driver collects information about the time between two key presses and then fills this ambient noise into a random number generator library.

Random data is stored in an entropy pool (the Linux kernel maintains an entropy pool to collect environmental noise from device drivers and other sources. In theory, the data in the entropy pool is completely random and can be generated A sequence of true random numbers. To track the randomness of the data in the entropy pool, the kernel estimates the randomness of the data when adding it to the pool. This process is called entropy estimation. The entropy estimate describes the number of random numbers contained in the pool. A larger value means more randomness in the data in the pool), which is "stirred" every time new data comes in. This stirring is actually a mathematical transformation that helps improve randomness. As data is added to the entropy pool, the system estimates how many truly random bits it has obtained.

It is important to determine the total amount of randomness. The problem is that some quantities are often less random than they appear when first considered. For example, adding a 32-bit number representing the number of seconds since the last keystroke was not actually providing a new 32-bit random information, since most keystrokes are close together.

After the bytes are read from /dev/random, the entropy pool uses the MD5 algorithm to hash the password, and the individual bytes in the hash are converted into numbers and then returned.

If there are no randomness bits available in the entropy pool, /dev/random waits until there is enough randomness in the pool, without returning a result. This means that if you use /dev/random to generate many random numbers, you will find that it is too slow to be practical. We often see /dev/random generate dozens of bytes of data and then produce no results for many seconds.

幸运的是有熵池的另一个接口可以绕过这个限制:/dev/urandom。即使熵池中没有随机性可用,这个替代设备也总是返回随机数。如果您取出许 多数而不给熵池足够的时间重新充满,就再也不能获得各种来源的合用熵的好处了;但您仍可以从熵池的 MD5 散列中获得非常好的随机数!这种方式的问题是,如果有任何人破解了 MD5 算法,并通过查看输出了解到有关散列输入的信息,那么您的数就会立刻变得完全可预料。大多数专家都认为这种分析从计算角度来讲是不可行的。然而,仍然认为 /dev/urandom 比 /dev/random 要“不安全一些”(并通常值得怀疑)。

Windows下没有/dev/random可用,但可以使用微软的“capicom.dll”所提供的CAPICOM.Utilities 对象。

以下是使用PHP时比用mt_rand()函数产生更好的伪随机数的一段例子代码:

<?php
// get 128 pseudorandom bits in a string of 16 bytes

$pr_bits = &#39;&#39;;

// Unix/Linux platform?
$fp = @fopen(&#39;/dev/urandom&#39;,&#39;rb&#39;);
if ($fp !== FALSE) {
$pr_bits .= @fread($fp,16);
@fclose($fp);
}

// MS-Windows platform?
if (@class_exists(&#39;COM&#39;)) {
try {
$CAPI_Util = new COM(&#39;CAPICOM.Utilities.1&#39;);
$pr_bits .= $CAPI_Util->GetRandom(16,0);

// if we ask for binary data PHP munges it, so we
// request base64 return value. We squeeze out the
// redundancy and useless ==CRLF by hashing...
if ($pr_bits) { $pr_bits = md5($pr_bits,TRUE); }
} catch (Exception $ex) {
// echo &#39;Exception: &#39; . $ex->getMessage();
}
}

if (strlen($pr_bits) < 16) {
// do something to warn system owner that
// pseudorandom generator is missing
}
?>

所以PHP要产生真随机数 还是要调用外部元素来支持的!

相关推荐:

PHP 随机数 C扩展随机数

基于php 随机数的深入理解

PHP函数:生成N个不重复的随机数,php 随机数_PHP教程

The above is the detailed content of PHP's true and false random numbers. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn