Bug #45301 [Ana]: Serious flaw in array_rand()

From: Date: Fri, 09 Sep 2016 02:45:56 +0000
Subject: Bug #45301 [Ana]: Serious flaw in array_rand()
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-203897@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=45301&edit=1

 ID:                 45301
 Updated by:         yohgaki@php.net
 Reported by:        payton2558 at googlemail dot com
 Summary:            Serious flaw in array_rand()
 Status:             Analyzed
 Type:               Bug
 Package:            Math related
 Operating System:   win32 only
 PHP Version:        *
 Assigned To:        pajoye
 Block user comment: N
 Private report:     N

 New Comment:

https://wiki.php.net/rfc/rng_fixes
Should be fixed by this.


Previous Comments:
------------------------------------------------------------------------
[2015-08-05 12:18:45] cmb@php.net

Related To: Bug #66718

------------------------------------------------------------------------
[2015-08-05 12:09:41] cmb@php.net

>> What about merging a patch that circulated in @internals that
>> made rand() and alias to mt_rand() and be done with this ?
>
> Because it may not fix the problem? (see the other report today
> and two weeks ago).

For reference, these reports are bug #45302 (which is a duplicate
of this ticket) and bug #45184 (which is about the scaling issue
that affects rand() as well as mt_rand(); see also PR #1416[1]).

[1] <https://github.com/php/php-src/pull/1416>

------------------------------------------------------------------------
[2015-07-30 11:32:13] cmb@php.net

The problem is the way array_rand() works, in combination with the
limited random number range available on Windows. The function
loops over all elements[1], calculating a new random number for
each, and checks whether to draw the current element[2]. However,
on Windows PHP_RAND_MAX == 32767, so this condition is likely to
be false for large num_avail. Particularly, when num_req == 1,
what is the default, the condition *can* only be true if either
randval == 0 or num_avail < PHP_RAND_MAX+1; the latter case
requires randval to be rather small still.

In practise, randval is always equal to zero for the OP's second
test script, so the random generator is always seeded to zero for
the next random operation.

On Linux, PHP_RAND_MAX == (2**31)-1, so this algorithm is less of
a problem, but still there may be issues for *very* large arrays.
If we can ignore these (so large an array won't easily fit into
memory), a solution would be to use php_mt_rand() instead of
php_rand() (and to seed the the MT random number generator
automatically).

[1] <https://github.com/php/php-src/blob/php-7.0.0beta2/ext/standard/array.c#L4547-L4573>
[2] <https://github.com/php/php-src/blob/php-7.0.0beta2/ext/standard/array.c#L4554>

------------------------------------------------------------------------
[2014-05-08 14:19:00] levim@php.net

Bug https://bugs.php.net/bug.php?id=67233 is a
duplicate of this one.

------------------------------------------------------------------------
[2014-02-15 15:49:10] timo dot fiersen at web dot de

Looks like my previous comment got lost... I was wondering if this is going to be fixed some day, it
seems to exist for ages already?

Or did this maybe just popped up again, because I'm experiencing the exact same problem with
5.5.x, calling array_random() kills all randomness.

PHP: 5.5.6 and 5.5.9 (both TS)
OS: Windows 7 x64

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    https://bugs.php.net/bug.php?id=45301


--
Edit this bug report at https://bugs.php.net/bug.php?id=45301&edit=1


Thread (16 messages)

« previous php.bugs (#203897) next »