Home >Backend Development >PHP Tutorial >Detailed explanation of pseudo-random numbers and true random numbers in PHP, detailed explanation of pseudo-random numbers_PHP tutorial
The first thing that needs to be stated is that the computer will not generate absolutely random random numbers, the computer 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, which means that 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 bitmap generated by Random.org (which uses atmospheric noise to generate random numbers, which is generated by thunderstorms in the air):
Random pictures generated by PHP’s rand() function under Windows:
Obviously, the pictures generated by the latter pseudo-random number generator have these obvious stripes.
The code to use PHP’s rand random function to generate this picture is:
Copy code The code is as follows:
//Need to enable gd library
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 principle of Linux random number generator:
The Linux operating system provides library data that is inherently random (or at least has components with strong randomness). 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. Theoretically, the data in the entropy pool is completely random and can generate true random numbers Sequence. 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 digits contained in the pool, and the larger the value. Indicates the more random the data in the pool. ), which "stirs" each 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.
Measuring the total amount of randomness is important. 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.
Once the bytes are read from /dev/random, the entropy pool performs a cryptographic hash using the MD5 algorithm, and the individual bytes in the hash are converted into numbers and 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.
Fortunately there is another interface to the entropy pool that can circumvent this limitation: /dev/urandom. This alternative device always returns random numbers even if no randomness is available in the entropy pool. If you take out many numbers without giving the entropy pool enough time to refill, you no longer get the benefit of the combined entropy from all sources; but you can still get very good random numbers from the MD5 hash of the entropy pool! The problem with this approach is that if anyone cracks the MD5 algorithm and learns something about the hashed input by looking at the output, your numbers immediately become completely predictable. Most experts agree that such an analysis is computationally unfeasible. However, /dev/urandom is still considered "less secure" (and generally questionable) than /dev/random.
There is no /dev/random available under Windows, but you can use the CAPICOM.Utilities object provided by Microsoft's "capicom.dll".
The following is an example code that uses PHP to generate better pseudo-random numbers than the mt_rand() function:
Copy code The code is as follows:
// get 128 pseudorandom bits in a string of 16 bytes
$pr_bits = '';
// Unix/Linux platform?
$fp = @fopen('/dev/urandom','rb');
if ($fp !== FALSE) {
$pr_bits .= @fread($fp,16);
@fclose($fp);
}
// MS-Windows platform?
if (@class_exists('COM')) {
try {
$CAPI_Util = new COM('CAPICOM.Utilities.1');
$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 'Exception: ' . $ex->getMessage();
}
}
if (strlen($pr_bits) < 16) {
// do something to warn system owner that
// pseudorandom generator is missing
}
?>
So if PHP wants to generate truly random numbers, it still needs to call external elements to support it!