4

I'm generating a sequence of pseudo random numbers with this code:

$seed = 1;
srand( $seed );
for($i=0; $i<10; $i++)
{
    echo rand(0,100) . "\n";
}
exit(0);

The following code outputs always (on my machine)

84
39
79
[....]
77
28
55

Can I rely on the fact that the output of the above code will be always the same?

If not, what could make it change?

For example may different versions of PHP give different results?

Or PHP running on different operative systems?

Paolo
  • 15,233
  • 27
  • 70
  • 91
  • 1
    [Same seed same numbers](https://3v4l.org/N2nCO) – Rizier123 Dec 05 '15 at 14:51
  • Not sure if 32-bit/64-bit PHP would give variation – Mark Baker Dec 05 '15 at 14:54
  • @MarkBaker Seems not to be the case: [32bit](https://eval.in/480799) [64bit](https://3v4l.org/X24sH) – Rizier123 Dec 05 '15 at 14:56
  • Nope, just tested it myself, no difference between 32-bit and 64-bit – Mark Baker Dec 05 '15 at 14:57
  • Though I'm running it on Windows, and I get a sequence of 99, 38, 79, 21, 75, 91, 42, 36, 47, 67.... so it may be that's OS will vary it. It's consistent against all versions, 32-bit or 64-bit on my Windows box, whereas if I run it on a Linux box I consistently get the same sequence of numbers as your 3v4l – Mark Baker Dec 05 '15 at 14:59

2 Answers2

3

If I run this code on Windows, I get a sequence of 99, 38, 79, 21, 75, 91, 42, 36, 47, 67. It's consistent against all versions, 32-bit or 64-bit on my Windows box.

Whereas if I run it on a Linux box I consistently get a sequence of 84, 39, 79, 80, 92, 19, 33, 77, 28, 55 no matter what version of PHP

So it isn't consistent between Operating Systems


However, if I use mt_srand() and mt_rand() instead of srand() and rand() then I do get consistence between Windows/Linux and different versions of PHP from 5.2 to 7.0

$seed = 1;
mt_srand( $seed );
for($i=0; $i<10; $i++)
{
    echo mt_rand(0,100) . "\n";
}
exit(0);

consistently gives 58, 0, 72, 94, 100, 87, 70, 100, 86, 76

Mark Baker
  • 209,507
  • 32
  • 346
  • 385
  • Warning, if memory serves right, it is NOT even consistent across different php versions. – hanshenrik Dec 05 '15 at 17:41
  • yup, Output for 5.2.1 - 7.0.0: 580729410087701008676 Output for 4.3.0 - 5.2.0: 89985189699593497888 -- http://3v4l.org – hanshenrik Dec 05 '15 at 17:46
  • 1
    Of course, if anybody is still using PHP <= 5.2.0 then they really should be ungrading, at least to a supported version – Mark Baker Dec 05 '15 at 17:47
  • Have fun next time PHP alters the mt_rand scheme, and your program/database depend on the old scheme, and you have to rewrite the old mt_rand in userland PHP :) – hanshenrik Dec 10 '15 at 08:16
  • @MarkBaker the accepted answer is not correct, as other people have pointed out. I've got 23,25,37,100,100,95,72,14,49,84 – Reza S Nov 17 '19 at 00:14
2

There's no guarantee between random numbers being the same across OS's or PHP versions. So best bet is to create your own psuedo random number generator, as pointed out in this blog post

Here's the code:

<?php

class Random {

    // random seed
    private static $RSeed = 0;

    // set seed
    public static function seed($s = 0) {
        self::$RSeed = abs(intval($s)) % 9999999 + 1;
        self::num();
    }

    // generate random number
    public static function num($min = 0, $max = 9999999) {
        if (self::$RSeed == 0) self::seed(mt_rand());
        self::$RSeed = (self::$RSeed * 125) % 2796203;
        return self::$RSeed % ($max - $min + 1) + $min;
    }

}

// set seed
Random::seed(42);

// echo 10 numbers between 1 and 100
for ($i = 0; $i < 10; $i++) {
    echo Random::num(1, 100) . ',';
}
echo "\n";

for ($i = 0; $i < 10; $i++) {
    echo Random::num() . ',';
}
echo "\n";

Which results in:

76,86,14,79,73,2,87,43,62,7,
393758,1684299,822150,2105442,337168,202955,203548,277673,1154689,1729772,

And obviously you'll get consistent results between different PHP versions. Note that you must provide a seed, otherwise this function will fall back on mt_rand and then you're at the mercy of the OS again!

Reza S
  • 9,480
  • 3
  • 54
  • 84