If I generate a number using: $num=rand(0, 1000);
, is it possible to guess what the next number will be?
Would I need to record a certain number of previously generated numbers? And how would I go about working out the next number?
Additional Information:
From random.org -
PHP Rand() image
True random image
Thanks to Derobert's answer:
I used the method posted in his answer to generate the following image
OpenSSL image
I used the following code to do this:
// Requires the 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 (random() === 1) {
imagesetpixel($im, $x, $y, $white);
}
}
}
imagepng($im);
imagedestroy($im);
function random(){
$num = unpack('L', openssl_random_pseudo_bytes(4, $is_strong));
if (!$is_strong) {
echo 'error';
}
else{
$lastDigit=substr($num[1], strlen($num[1])-1, 1);
if($lastDigit<=4) return 0;
return 1;
}
}
Credits to Bo
Yes, it's possible, php's rand
is apparently just using the underlying C library's rand, which is a pseudo-random number generator.
How much output you'd need to observe depends on the exact algorithm used by the C library, which varies from platform to platform (and sometimes even version to version). The number of outputs you need to observer is probably fewer than ten.
If your C library is particularly bad, you could try mt_rand
which uses the Mersenne Twister algorithm. Note that this is still predictable.
If you need unpredictable random numbers, then use openssl_random_pseudo_bytes
and make sure crypto_strong is true afterwards. Note that it returns a binary string; to get a number you'll have to use something like unpack
:
$num = unpack('L', openssl_random_bytes(4, $is_strong));
if (!$is_strong) {
... // handle error
}
Also note that will return a number between 0 and 2³²=4294967296, not 0–1000, so you'll need to deal with that.
PHP will generate the same sequence of numbers for the same seed. So you would have to find out the seed and then log the numbers:
php > srand(1);
php > echo rand(1,100);
85
php > echo rand(1,100);
40
php > srand(1);
php > echo rand(1,100);
85
php > echo rand(1,100);
40
Or you have a look at the PHP source!
rand()
generates a pseudo-random sequence. If you would like a predictable (read reproducable) sequence, you need to seed the random generator using srand()
.
Try running the below script twice in a row:
<?php
$seed = 2;
srand($seed);
foreach(range(1, 100) as $i) var_dump(rand(0, 100));