4

I was testing PHP rand function to write on a image. Of course the output shows that it's not so random. The code I used:

<?php 
header('Content-Type: image/png');
$lenght = 512;
$im = imagecreatetruecolor($lenght, $lenght);
$blue = imagecolorallocate($im, 0, 255, 255);
for ($y = 0; $y < $lenght; $y++) {
    for ($x = 0; $x < $lenght; $x++) {
        if (rand(0,1) == 0) {
            imagesetpixel($im, $x, $y, $blue);
        }
    }
}       
imagepng($im);
imagedestroy($im);
?>

My question is, if I use image width/lenght (variable $lenght in this example) number like 512, 256 or 1024, it is very clear that it's not so random. When I change the variable to 513 for an example, it is so much harder for human eye to detect it. Why is that? What is so special about these numbers?

512:

512 pixels

513:

513 pixels

Edit: I'm running xampp on Windows to test it.

2

1 Answer 1

9

This is a known bug which isn't related to PHP, but inherant to the windows API used by PHP. The random function of this API is very bad.

This problem will not exist on Linux or MacOS (or any other system).

You can learn more about this here: http://cod.ifies.com/2008/05/php-rand01-on-windows-openssl-rand-on.html

If it is more visible with some value, this is mostly because of the dimensions of the image, and the clear lines formed by the pattern. This is definitively linked to our perception, some patterns looks more random than others.

The human brain random function is very buggy. What we see as random or not isn't reliable at all. This is a known phenomenon but off topic here.

3
  • Windows doesn't provide a random. I believe MSVC++ provides a macro for it that points at the CRT's rand though. Windows does provide OpenSSL-style random number generators (CryptGenRandom and friends), but PHP does not use them. Nov 25, 2011 at 3:38
  • @BillyONeal, that is right. I should have said, that standard rand function in C provided by MSVCRT is bugguy. That was an oversimplification and I never meant that generate random number on windows was impossible.
    – deadalnix
    Nov 25, 2011 at 9:35
  • It's not buggy. It's essentially the same rand provided by glibc (also an LCG) and pretty much every C implementation I've ever heard of. The C standard never said that the rand provided had to be cryptographically secure. (If nothing else, making such requirements on small microcontrollers would be hard) Linear congruential generators have the advantage that they require very little space to maintain state -- typically sizeof(int). There are better generators in terms of randomness but they require a ton more space. Mersenne Twister, for instance is typically 624*sizeof(int). Nov 25, 2011 at 21:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.