In PHP, how do I generate a big pseudo-random number?

Alix Axel picture Alix Axel · Sep 26, 2009 · Viewed 7.8k times · Source

I'm looking for a way to generate a big random number with PHP, something like:

mt_rand($lower, $upper);

The closer I've seen is gmp_random() however it doesn't allow me to specify the lower and upper boundaries only the number of bits per limb (which I've no idea what it is).

EDIT: Axsuuls answer seems to be pretty close to what I want and very similar to gmp_random however there seems to be only one flaw in one scenario.

Suppose I wan't to get a random number between:

  • 1225468798745475454898787465154

and:

  • 1225468798745475454898787465200

So if the function is called BigRandomNumber():

BigRandomNumber($length = 31);

This can easily return 9999999999999999999999999999999 which is out of the specified boundary.

How can I use a min / max boundary instead of a length value?

BigRandomNumber('1225468798745475454898787465154', '1225468798745475454898787465200');

This should return a random number between 1225468798745475454898787465 [154 .. 200].

For the reference I believe the solution might have to make use of the function supplied in this question.

EDIT: The above post was deleted, here it is:

function compare($number1, $operator, $number2) {
  $x = bccomp($number1, $number2);

  switch($operator) {
    case '<':
      return -1===$x;
    case '>':
      return 1===$x;
    case '=':
    case '==':
    case '===':
      return 0===$x;
    case '!=':
    case '!==':
    case '<>':
      return 0!==$x;
  }
}

Answer

Robert K picture Robert K · Oct 1, 2009

Try the following:

function BigRandomNumber($min, $max) {
  $difference   = bcadd(bcsub($max,$min),1);
  $rand_percent = bcdiv(mt_rand(), mt_getrandmax(), 8); // 0 - 1.0
  return bcadd($min, bcmul($difference, $rand_percent, 8), 0);
}

The math is as following: multiply the difference between the minimum and maximum by a random percentage, and add to the minimum (with rounding to an int).