Hi all, Following code is problematic and needs proper reseeding to work.
// We need the same random numbers here mt_srand(1234); for ($i=0; $i < 10; $i++) { $my_rand[] = mt_rand(); } Somewhere later in code // We need somewhat random numbers for non CS purpose for ($i=0; $i < 10; $i++) { $my_other_rand[] = mt_rand(); } $my_other_rand array is not random at all for the app. This applies to rand()/srand() as well as all functions that use rand and rand/MT rand internally. e.g. shuffle(). rand() is alias of mt_rand() in PHP 7.1, it can cause serious problem. i.e. srand(1234) forces mt_rand() to generate non random numbers. In addition, this behavior persists across requests because once BG(mt_rand_is_seeded)/BG(rand_is_seeded) are set to 1, they are kept for the process. Therefore, subsequent mt_rand()/rand(), including any functions use rand/MT rand internally such as shuffle(), call in other requests are not random. In order to get random numbers, we need to reseed RNG. Currently, it is possible to reseed like (int overflow is ignored) $seed = unpack("l", file_get_contents("/dev/urandom", false, NULL, 0, 4)); mt_srand($seed[1]); for ($i=0; $i < 10; $i++) { $my_other_rand[] = mt_rand(); } OR for PHP 7 mt_srand(random_int(PHP_INT_MIN, PHP_INT_MAX)); for ($i=0; $i < 10; $i++) { $my_other_rand[] = mt_rand(); } Requiring these reseeding code for most mt_rand()/rand() calls is not preferred behavior. Proposal: 1) Add BG(mt_rand_is_user_seeded) and BG(rand_is_user_seeded). If they are 1, set BG(mt_rand_is_seeded)=0 and BG(rand_is_seeded)=0. 2) Make srand(0) and mt_srand(0) to force RNG reseeding by PHP. Outcome: 1) resolves "across requests" non random numbers. 2) simplifies reseeding. Problem: 1) Added new BG values are BC for released versions. Simply reseeding by current GENERATE_SEED() macro is weak and too easy to be guessed even with MT rand. i.e. Setting BG(mt_rand_is_seeded)=0 and BG(rand_is_seeded)=0 at RINIT is not exactly a good idea. (There is improvement discussion in "Improving mt_rand() seed" thread) 2) Manual reseeding API, srand(0)/mt_srand(0), is not compatible with older versions. Open Issue: 1) and 2), apply these to released versions or not. This idea is acceptable, but I don't like this idea myself. It seems we should do something for this, documentation for released versions at least. Any better ideas are appreciated. Regards, -- Yasuo Ohgaki yohg...@ohgaki.net