Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to predict rand(0,10) in PHP?

Tags:

php

math

I have a script where I use the rand function in PHP. Now I read some ghost stories that its real easy to predict those outcomes. Is this possible from the client-side?

For example, let say we have a rand(0,10). Is it possible to predict the next number?

like image 245
S.Visser Avatar asked Oct 04 '12 14:10

S.Visser


4 Answers

rand() function returns a pseudorandom number . This does NOT mean that the next number can be predicted. However this image can explain the concept of word pseudorandom

rand

You can read this article

the image is generated from a simple loop with rand function on windows system.

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)) {
            imagesetpixel($im, $x, $y, $white); 
        } 
    } 
} 
imagepng($im); imagedestroy($im);

It's not so random, really? But now that you know it... you can predict the next number?

The difference between true random number generators (TRNGs) and pseudo-random number generators (PRNGs) is that TRNGs use an unpredictable physical means to generate numbers (like atmospheric noise), and PRNGs use mathematical algorithms (completely computer-generated)

[...]

Not many PRNGs will produce an obvious visual pattern like this, it just so happens to be a really bad combination of language (PHP), operating system (Windows), and function (rand()).

like image 121
Luca Rainone Avatar answered Oct 06 '22 01:10

Luca Rainone


You'd have to brute-force the state of the PRNG. http://crypto.di.uoa.gr/CRYPTO.SEC/Randomness_Attacks_files/paper.pdf

PHP's rand() uses the underlying standard library implementation, this is different based on the operating system.

So first step, define the operating system.

Next step, get the source code for the Rand() function and the code that seeds it.

For simplicity lets assume the seed for the PRNG is something like the millisecond time of the server. So, the HTTP request comes in, PHP seeds the PRNG and executes rand(0,10). If you want to predict that you would...

  • Sync your client's clock to the server's, statistically deriving the exact time from sending HTTP request to the server and reading the response HTTP header with the time stamp.

  • Seed your client PRNG (that is the same implementation as the server's) with a predicted future time that you will request rand(0,10) from the server. Run rand(0,10) on the client, send the request at the exact future time to the server and the results would be the same.

  • Ping times, processing times, etc make this a fairly brute-force approach.

Really, over the internet (not having direct access to the server), you aren't going to have much luck predicting the results of PHP's rand() function.

like image 45
Louis Ricci Avatar answered Oct 05 '22 23:10

Louis Ricci


From the rand manual:

A pseudo random value between min (or 0) and max (or getrandmax(), inclusive).

So, random is not random, but pseudo random. If you know how the caluclation is done, and know the initial value one can predict (calculate) the next value.

If you need a true random value, you need a other algorithm. Based on white noise, for example.

like image 34
JvdBerg Avatar answered Oct 06 '22 00:10

JvdBerg


The value returned by rand() is only a pseudo random value.

This means, that it might be possible to calculate the number if you got access to the machine, but that's still really unlikely to happen. A end-user which just sees the output of PHP and has no access to machine has no possible option of calculation or predicting the next value. The output of multiple rand() calls within ONE execution of a php script might *technically *be predictable, but this cannot be used anway, because the user does only see the output of ONE WHOLE execution, having no chance to interact while the PHP script is executing.

This is the procedure used to generate the seed for PHP's rand():

#ifdef PHP_WIN32
#define GENERATE_SEED() (((long) (time(0) * GetCurrentProcessId())) ^ ((long) (1000000.0 * php_combined_lcg(TSRMLS_C))))
#else
#define GENERATE_SEED() (((long) (time(0) * getpid())) ^ ((long) (1000000.0 * php_combined_lcg(TSRMLS_C))))
#endif

As of PHP 4.2.0, The random number generator is seeded automatically.

like image 32
Zulakis Avatar answered Oct 06 '22 00:10

Zulakis