Why rand() isn't really random?
Asked Answered
G

3

11

I wanted to put random points on an image (stars in space for some little fun side project)

I have this simple script.

<?php
$gd = imagecreatetruecolor(1000, 1000);
$white = imagecolorallocate($gd, 255, 255, 255);

for ($i = 0; $i < 100000; $i++) 
{
    $x = rand(1,1000);
    $y = rand(1,1000);

    imagesetpixel($gd, round($x),round($y), $white);
}

header('Content-Type: image/png');
imagepng($gd);
?>

Keep in mind this is just for testing, that is why I put 100000 in for loop so it shows the pattern I noticed emerging. We have 1 million pixel to use, still random X and Y creates this pattern instead: enter image description here

So it is far from random. I know rand is not real random, that is why it isn't good for cryptography. But I find no information about how it works and what should I do to avoid patterns like this.

Girardi answered 28/7, 2015 at 11:42 Comment(0)
S
11

Linear congruential random number generators (which is what PHP rand uses) will always display autocorrelation effects on an x-y plot.

You will have better results with mt_rand. This is a Mersenne Twister generator.

Septimal answered 28/7, 2015 at 11:46 Comment(2)
Thank you for the keywords I searching for. Really helps. I know lot about PHP and programming in general, but I am mostly self educated tough, so I lack some technical terms. I will accept this ASAP.Polinski
And mt_rand really does the job. It is seem random and change every time I run it. i.imgur.com/DoeNFB9.png Thank you again.Polinski
A
1

Rest assured: As of PHP 7.1.0, rand() uses the same random number generator as mt_rand().

This only is an issue for PHP < 7.1 see the Docs

Awl answered 24/1, 2020 at 14:29 Comment(1)
Incredible that after almost 5 years I still get notifications about this question, and even meaningful ones like this.Polinski
J
1

We used in our company mt_rand() to generate a 16 character long random ident. We had 3500000 records in our database and idents were colliding.

We used "abcdefghijklmnopqrstuvwxyz0123456789" as our charset and were picking "random" chars with mt_rand() for our ident.

The possibilities are theoretically 16^32. Thats 340282366920938463463374607431768211456 (340 undecillion)

And yet there were collisions...

we switched to random_int() and hopefully never get collisions again

Jerkwater answered 13/9, 2023 at 11:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.