Here is a reason why not to use rand().

Discussions of secure PHP coding. Security in software is important, so don't be afraid to ask. And when answering: be anal. Nitpick. No security vulnerability is too small.

Moderator: General Moderators

User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Here is a reason why not to use rand().

Post by kaisellgren »

Hello,

I was playing around with lots of image manipulation and randomness. I just thought that maybe there's someone who might be interested in this so I decided to make this post.

A picture, which represents the randomness of the function rand():
Image

A picture, which represents the randomness of the function mt_rand():
Image

So if anyone ever needs to know why mt_rand() is better, here's one reason. :)

The images were both made with the same algorithm. I only added mt_ in front of rand() function. And look how much it differs. The reason why my script produces more patterns is due to the nature of repetitive random. Read the source code of rand(), and you will realise that's not the best thing rand() can cope with. I tried to make the picture for rand() more pattern-like on purpose. So I exploited it. But it's still fair comparison, because they both produced the images with the same algorithm. However, this is pretty much extreme-case, so this does not often occur. Basically on purpose. But I still wanted to show off everybody, that rand() is not as capable of producing more quality entropy than mt_rand() is. For source, look below.
Last edited by kaisellgren on Tue Dec 30, 2008 6:35 pm, edited 1 time in total.
User avatar
jaoudestudios
DevNet Resident
Posts: 1483
Joined: Wed Jun 18, 2008 8:32 am
Location: Surrey

Re: Here is a reason why not to use rand().

Post by jaoudestudios »

S**T! rand() really sucks!

Thanks kaisellgren :)
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: Here is a reason why not to use rand().

Post by Eran »

now I know what function to use if I want to render the universe ;)

nice pics :)
User avatar
omniuni
Forum Regular
Posts: 738
Joined: Tue Jul 15, 2008 10:50 pm
Location: Carolina, USA

Re: Here is a reason why not to use rand().

Post by omniuni »

I noticed this a long time ago with QBASIC. I wrote a program that drew dots on the screen "randomly". There was always a noticeable movement of "lines" through the randomness. Seems rand() has that same issue.
User avatar
pcoder
Forum Contributor
Posts: 230
Joined: Fri Nov 03, 2006 5:19 am

Re: Here is a reason why not to use rand().

Post by pcoder »

Very nice demonstration, Now i always go for the mt_rand().
Thanks kaisellgren
User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Re: Here is a reason why not to use rand().

Post by kaisellgren »

omniuni wrote:I noticed this a long time ago with QBASIC. I wrote a program that drew dots on the screen "randomly". There was always a noticeable movement of "lines" through the randomness. Seems rand() has that same issue.
Same 'issue' can be found in Commodore 64 too ;)
User avatar
papa
Forum Regular
Posts: 958
Joined: Wed Aug 27, 2008 3:36 am
Location: Sweden/Sthlm

Re: Here is a reason why not to use rand().

Post by papa »

Hehe nice :)

Just felt like watching Return of the Jedi for some reason.
User avatar
Greenconure
Forum Commoner
Posts: 30
Joined: Mon Jun 16, 2008 8:19 am

Re: Here is a reason why not to use rand().

Post by Greenconure »

Awesome. Any chance you could post the source(s)?

Thanks,
Greenconure
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

Re: Here is a reason why not to use rand().

Post by onion2k »

I suspect it's more likely to be an implementation issue than a problem with the rand() function.
User avatar
omniuni
Forum Regular
Posts: 738
Joined: Tue Jul 15, 2008 10:50 pm
Location: Carolina, USA

Re: Here is a reason why not to use rand().

Post by omniuni »

Hm, why do you say that Onion?

The same code produced both images, save the random function used, rand() is noted as not being a good option on the PHP web page itself, and as has been noted above, it's not specific to PHP; this is an old issue that has been noted on other platforms and other "random" implementations.
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

Re: Here is a reason why not to use rand().

Post by onion2k »

omniuni wrote:Hm, why do you say that Onion?
Because I've written loads of code that applies random filters to images using rand() and never had this sort of problem, and I know there are lots of pitfalls with implementing rand() that can make return results that aren't random. The same code with mt_rand() will produce random results. That doesn't make rand() the problem.

Like I said though, it's just something I suspect. I could well be wrong. We'll need to see the code to have any level of certainly.
User avatar
omniuni
Forum Regular
Posts: 738
Joined: Tue Jul 15, 2008 10:50 pm
Location: Carolina, USA

Re: Here is a reason why not to use rand().

Post by omniuni »

Applying "random" filters, yes, but I believe this is not a filter, but literally a graphical representation of the rand() function.
User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Re: Here is a reason why not to use rand().

Post by kaisellgren »

onion2k wrote:Because I've written loads of code that applies random filters to images using rand() and never had this sort of problem, and I know there are lots of pitfalls with implementing rand() that can make return results that aren't random. The same code with mt_rand() will produce random results. That doesn't make rand() the problem.

Like I said though, it's just something I suspect. I could well be wrong. We'll need to see the code to have any level of certainly.
You are partly right, but I think you misunderstood the purpose of this. The purpose was to show that mt_rand() produces better randoms. I did not say that mt_rand() produces good randoms, or rand() produces good random, but I said mt_rand() produces better randoms than rand(). It's a comparative. Neither of these two functions should be used blindly for cryptagraphic use as explained in viewtopic.php?f=34&t=92271

Whether you face these kind of problems when applying image related filters or not, it depends much on the way you implement the use of rand() function. Here I tried to show the randomness of these functions with a representation of an image. I tried to exploit the unrandomness of rand() and take the advantage of it to produce a picture that looks pattern-like. If I wanted, I could use rand() to produce universums, too. But the purpose was to show off how mt_rand() produces better randoms than rand().

Feel free to experiment this little piece of script.

Code: Select all

<?php
 
// Telling the browser what to handle
header('Content-Type: image/png');
 
// Picture size and randomness settings
$size = 512;
$randask = pi();
$randsize = log(256,$randask);
 
// Creating true color picture
$im = imagecreatetruecolor($size,$size);
 
// Background white
imagerectangle($im,0,0,$size,$size,imagecolorallocate($im,255,255,255));
 
// Looping through all pixels of the image
for ($a = 0;$a < $size;$a++)
 {
  for ($b = 0;$b < $size;$b++)
   {
    $mpa = array();
    for ($c = 0;$c < $randsize;$c++)
     $mpa[] = rand(0,$randask);
    $level = $mpa[0];
    for ($c = 1,$d = count($mpa);$c < $d;$c++)
     $level *= $mpa[$c];
    imageline($im,$a,$b,$a,$b,imagecolorallocate($im,$level-1,$level-1,$level-1));
   }
 }
 
// Output and destroy
imagepng($im);
imagedestroy($im);
 
?>
I used value 2 instead of pi() in the pictures shown in the top of this thread.
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: Here is a reason why not to use rand().

Post by josh »

Looks like a bug to me. No way rand is producing that pattern, if this isnt a bug you need to log off of devnet, drive to the nearest store and buy a lottery ticket, now. Rand() is fine unless you're programming gambling websites / medical software or something.

Why dont you try this instead, do a loop N times, each time placing a dot at the point { RAND, RAND } ( where each RAND is a separate call to rand() ). I guarantee you won't see any definable horizontal lines quite like in the image you have shared with us

Code: Select all

<?php
$size = 400;
$im = imagecreate( $size, $size );
$bg = imagecolorallocate( $im, 0,0,0);
$red = imagecolorallocate( $im, 255,0,0);
for( $i=0; $i<9999; $i++ )
{
    // comment out for black
    imagesetpixel( $im, mt_rand(0,$size), mt_rand(0,$size), $red );
}
header('Content-Type:image/jpeg');
imagejpeg($im);
Blank image:
Image

rand:
Image

mt_rand:
Image

The bug is that you're calling $level-1, which is why the visual pattern emerges in your image. Also they both arguably have "patterns", in the mt_rand I could argue the dots are clustered and therefore predictable. It really is a philosophical question of what truly is random? Do you believe in determinism ( we have control over our surroundings ) or do you believe that our surroundings control us, that we just obey the laws of physics and that determines our fate. That being said mt_rand is going to be less predictable by a human or current AI / bot / machine than rand will be.
Last edited by josh on Tue Dec 30, 2008 6:06 pm, edited 1 time in total.
User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Re: Here is a reason why not to use rand().

Post by kaisellgren »

jshpro2 wrote:Looks like a bug to me. No way rand is producing that pattern, if this isnt a bug you need to log off of devnet, drive to the nearest store and buy a lottery ticket, now. Rand() is fine unless you're programming gambling websites / medical software or something.

Why dont you try this instead, do a loop N times, each time placing a dot at the point { RAND, RAND } ( where each RAND is a separate call to rand() ). I guarantee you won't see any definable horizontal lines quite like in the image you have shared with us

Code: Select all

<?php
$size = 400;
$im = imagecreate( $size, $size );
$bg = imagecolorallocate( $im, 0,0,0);
$red = imagecolorallocate( $im, 255,0,0);
for( $i=0; $i<9999; $i++ )
{
    // comment out for black
    imagesetpixel( $im, mt_rand(0,$size), mt_rand(0,$size), $red );
}
header('Content-Type:image/jpeg');
imagejpeg($im);
The bug is that you're calling $level-1, which is why the visual pattern emerges in your image
The $level-1 does not produce any bugs. It's there, because the value of $level is from 0 to 256, and since 256 is not a proper value it's decreased by one. -1 seems to be a proper value, it's same as 0.

And whether rand() is usable, it depends where you need it for. For cryptographic use it is not usable at all.

And btw, your code does not exploit the weakness of rand(). At least not much.
Last edited by kaisellgren on Tue Dec 30, 2008 6:07 pm, edited 1 time in total.
Post Reply