Author Topic: PHP script for repeatable (?) random number generation  (Read 1058 times)

Offline andrewjbaker

  • Level 17
  • *
  • Posts: 154
  • Reputation: +2/-0
    • View Profile
    • Fleeting Fantasy
PHP script for repeatable (?) random number generation
« on: December 06, 2010, 08:35:55 PM »
"OK, OK, repeatable random number generation?!?!"

"Has this guy gone mad?"

Well I haven't, I assure you.

I'm in the process of generating procedural content for a simplistic text-based hack and slash PBBG and I had intended to use PHP's srand() function to guarantee that the content I generate is consistent across the execution of all of my unit tests.

But, it seems that PHP's srand() doesn't operate quite as originally anticipated. At some point, someone appears to have made a decision (a decision?) to nullify srand(); stated bluntly, srand() doesn't work (http://www.mail-archive.com/debian-bugs-dist@lists.debian.org/msg813274.html). Because developers were using PHP's rand() and srand() functions for cryptographic applications and because PHP's rand() and srand() functions are statistically too repeatable, the mt_rand() series of functions were introduced as a more secure replacement. That's fine.

But what if you don't care for security given the nature of the code you're working on? What if you're generating game content and cryptography is nowhere to be seen?

Here's my quick and dirty (and yet repeatable across execution) replacement for PHP's getrandmax(), rand(), and srand() functions:

Code: [Select]
<?php
$_next 
1;

function 
xgetrandmax()
{
    return 
32767;
}

function 
_xrand()
{
    global 
$_next;

    
$_next = (int) $_next 1103515245 12345;
    return (int) 
abs($_next 65536 % (xgetrandmax() + 1));
}

function 
xrand($min NULL$max NULL)
{
    if (isset(
$min) && isset($max)) {
        return 
_xrand() % ($max $min 1) + $min;
    }
    return 
_xrand();
}

function 
xsrand($seed)
{
    global 
$_next;

    
$_next abs((int) $seed % (xgetrandmax() + 1));
}

Use the script largely as you will; if you're after an RNG for cryptographic purposes, please don't use it. But if you do require consistent repeatable random number generation in your unit tests, each seeded with srand(364) for example, go ahead and feel free.

Cheers, Andy.

P.S. Maybe the term 'decision' is a little harsh. Further Googling has shown that suhosin.srand.ignore is, quite literally, being ignored regardless of whether it equals 0 or 1, at the very least on Debian running PHP 5.3.3-4 with Suhosin-Patch.
Currently working on an HTML5 canvas 2.5D landscape renderer and a PBBG that uses it (http://fleetingfantasy.com/). The development blog's at http://fleetingfantasy.wordpress.com/.
What are BBGameZone members working on? See the game list.
irc.freenode.net, #bbg

Offline Nox

  • Level 35
  • **
  • Posts: 768
  • Reputation: +12/-2
    • View Profile
Re: PHP script for repeatable (?) random number generation
« Reply #1 on: December 07, 2010, 01:12:28 AM »
Nice
Though maybe:
1) What about mt_srand() ?
2) Unit testing, interfaces and all of a sudden you have there a global variable :) it's not possible to make it a function's parameter?
Or better in case of xsrand just return it and assign outside
Meet us at an IRC irc.freenode.net #bbg as well
https://vimeo.com/36579366 (a must-watch) | Join BOINC - no longer a hype, but you can help never the less

Offline Chris

  • Game Owner
  • Level 35
  • *
  • Posts: 2,217
  • Reputation: +28/-1
    • View Profile
Re: PHP script for repeatable (?) random number generation
« Reply #2 on: December 07, 2010, 04:29:30 AM »
"Since 5.2.1  The Mersenne Twister implementation in PHP now uses a new seeding algorithm by Richard Wagner. Identical seeds no longer produce the same sequence of values they did in previous versions. This behavior is not expected to change again, but it is considered unsafe to rely upon it nonetheless."

They broke the compatibility with previous PHP versions, mt_rand() still provide identical results within the same PHP version.

Also note that rand() and srand() is system dependent while mt_rand() and mt_srand() is system independent and is supposed to provide identical results on all platforms.


Yes, if your seed persistence is extremely important you should not trust PHP devs since they obviously do not care about the whole persistent content generation functionality, still it is good enough to rely on the standard solution (and much more efficient) if you don't plan to upgrade PHP versions all the time.

EDIT: I never did any persistent srand generator in PHP, so this above is based on my readings.
« Last Edit: December 07, 2010, 05:17:55 AM by Chris »

Offline andrewjbaker

  • Level 17
  • *
  • Posts: 154
  • Reputation: +2/-0
    • View Profile
    • Fleeting Fantasy
Re: PHP script for repeatable (?) random number generation
« Reply #3 on: December 07, 2010, 07:23:13 AM »
Quote
2) Unit testing, interfaces and all of a sudden you have there a global variable  it's not possible to make it a function's parameter?
Or better in case of xsrand just return it and assign outside

This is one of those instances, Nox, where getting something working was more important than worrying about OOP best practice.  :P

In an ideal world, it'd be OOP'd. And, that's my ultimate plan.

I just thought I'd share the procedural code with you all so that those who don't /do/ OOP can benefit alongside those that do /do/ OOP.  ;)
Currently working on an HTML5 canvas 2.5D landscape renderer and a PBBG that uses it (http://fleetingfantasy.com/). The development blog's at http://fleetingfantasy.wordpress.com/.
What are BBGameZone members working on? See the game list.
irc.freenode.net, #bbg

Offline Chris

  • Game Owner
  • Level 35
  • *
  • Posts: 2,217
  • Reputation: +28/-1
    • View Profile
Re: PHP script for repeatable (?) random number generation
« Reply #4 on: December 07, 2010, 10:15:59 AM »
Quote
2) Unit testing, interfaces and all of a sudden you have there a global variable  it's not possible to make it a function's parameter?
Or better in case of xsrand just return it and assign outside

This is one of those instances, Nox, where getting something working was more important than worrying about OOP best practice.  :P

In an ideal world, it'd be OOP'd. And, that's my ultimate plan.

I just thought I'd share the procedural code with you all so that those who don't /do/ OOP can benefit alongside those that do /do/ OOP.  ;)
Wrong! Everyone knows you should do things the way below :D

Code: [Select]
#include <stdio.h>

// The HelloWorld class definition.
class HelloWorld
{
   public:
     HelloWorld() {}  // Constructor.
     ~HelloWorld() {}  // Destructor.
   void print()
   {
     printf("Hello World!\n");
   }
};

int main()
{
  HelloWorld a;  // Create a HelloWorld object.
  a.print();  // Send a "print" message to the object.
  return 0;
}
That's the *proper* way of coding "Hello World" :D

Offline Harkins

  • Level 28
  • **
  • Posts: 424
  • Reputation: +11/-2
  • Coder, blogger, entrepreneur.
    • View Profile
    • Push CX - Blog
Re: PHP script for repeatable (?) random number generation
« Reply #5 on: December 07, 2010, 10:51:22 AM »
Huh, I always thought it was:

Code: [Select]
puts "Hello, World!"

The string is an object, the method puts is on the Kernel module that's included by the base object. Objects all the way down, no noise.

Visit #bbg on irc.freenode.net to talk browser games anytime.

Offline Nox

  • Level 35
  • **
  • Posts: 768
  • Reputation: +12/-2
    • View Profile
Re: PHP script for repeatable (?) random number generation
« Reply #6 on: December 07, 2010, 02:15:41 PM »
Objects->witchcraft and heresy! Spread the word of the holy machine code!
Meet us at an IRC irc.freenode.net #bbg as well
https://vimeo.com/36579366 (a must-watch) | Join BOINC - no longer a hype, but you can help never the less

 


SimplePortal 2.3.3 © 2008-2010, SimplePortal