Bug #45301 [Com]: Serious flaw in random related functions

From: Date: Sat, 15 Feb 2014 15:49:11 +0000
Subject: Bug #45301 [Com]: Serious flaw in random related functions
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-184304@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
 Comment by:         timo dot fiersen at web dot de
 Reported by:        payton2558 at googlemail dot com
 Summary:            Serious flaw in random related functions
 Status:             Assigned
 Type:               Bug
 Package:            Math related
 Operating System:   win32 only
 PHP Version:        *
 Assigned To:        pajoye
 Block user comment: N
 Private report:     N

 New Comment:

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


Previous Comments:
------------------------------------------------------------------------
[2009-10-30 22:15:26] scott046 at hotmail dot com

If anybody is interested, this code:

<?php

print("20 element array; apparently no problem<br>\r\n");
$array1 = array();
$counter1 = 0;
while($counter1 < 20) {
	$array1[] = $counter1;
	$counter1++;
}
$print_counter1 = 0;
while($print_counter1 < 10) {
	print($array1[array_rand($array1)] . "<br>\r\n");
	$print_counter1++;
}

print("<br>\r\n<br>\r\n200 element array; apparently no
problem<br>\r\n");
$array1 = array();
$counter1 = 0;
while($counter1 < 200) {
	$array1[] = $counter1;
	$counter1++;
}
$print_counter1 = 0;
while($print_counter1 < 10) {
	print($array1[array_rand($array1)] . "<br>\r\n");
	$print_counter1++;
}

print("<br>\r\n<br>\r\n2000 element array; apparently no
problem<br>\r\n");
$array1 = array();
$counter1 = 0;
while($counter1 < 2000) {
	$array1[] = $counter1;
	$counter1++;
}
$print_counter1 = 0;
while($print_counter1 < 10) {
	print($array1[array_rand($array1)] . "<br>\r\n");
	$print_counter1++;
}

print("<br>\r\n<br>\r\n10000 element array; apparent problem: mild
repetition<br>\r\n");
$array1 = array();
$counter1 = 0;
while($counter1 < 10000) {
	$array1[] = $counter1;
	$counter1++;
}
$print_counter1 = 0;
while($print_counter1 < 10) {
	print($array1[array_rand($array1)] . "<br>\r\n");
	$print_counter1++;
}

print("<br>\r\n<br>\r\n20000 element array; apparent problem:
repetition<br>\r\n");
$array1 = array();
$counter1 = 0;
while($counter1 < 20000) {
	$array1[] = $counter1;
	$counter1++;
}
$print_counter1 = 0;
while($print_counter1 < 10) {
	print($array1[array_rand($array1)] . "<br>\r\n");
	$print_counter1++;
}

print("<br>\r\n<br>\r\n30000 element array; apparent problem:
repetition<br>\r\n");
$array1 = array();
$counter1 = 0;
while($counter1 < 30000) {
	$array1[] = $counter1;
	$counter1++;
}
$print_counter1 = 0;
while($print_counter1 < 10) {
	print($array1[array_rand($array1)] . "<br>\r\n");
	$print_counter1++;
}

print("<br>\r\n<br>\r\n50000 element array; apparent problem:
repetition<br>\r\n");
$array1 = array();
$counter1 = 0;
while($counter1 < 50000) {
	$array1[] = $counter1;
	$counter1++;
}
$print_counter1 = 0;
while($print_counter1 < 10) {
	print($array1[array_rand($array1)] . "<br>\r\n");
	$print_counter1++;
}

print("<br>\r\n<br>\r\n100000 element array; 32767=2^15-1 repeating;
<br>\r\n");
$array1 = array();
$counter1 = 0;
while($counter1 < 100000) {
	$array1[] = $counter1;
	$counter1++;
}
$print_counter1 = 0;
while($print_counter1 < 10) {
	print($array1[array_rand($array1)] . "<br>\r\n");
	$print_counter1++;
}

print("<br>\r\n<br>\r\n200000 element array; 32767=2^15-1 repeating;
<br>\r\n");
$array1 = array();
$counter1 = 0;
while($counter1 < 200000) {
	$array1[] = $counter1;
	$counter1++;
}
$print_counter1 = 0;
while($print_counter1 < 10) {
	print($array1[array_rand($array1)] . "<br>\r\n");
	$print_counter1++;
}

print("<br>\r\n<br>\r\n300000 element array; 32767=2^15-1 repeating;
<br>\r\n");
$array1 = array();
$counter1 = 0;
while($counter1 < 300000) {
	$array1[] = $counter1;
	$counter1++;
}
$print_counter1 = 0;
while($print_counter1 < 10) {
	print($array1[array_rand($array1)] . "<br>\r\n");
	$print_counter1++;
}

?>

produces this output:

20 element array; apparently no problem
16
5
11
9
17
7
15
2
8
9


200 element array; apparently no problem
43
25
147
127
127
2
109
14
67
165


2000 element array; apparently no problem
26
1513
1882
1721
590
917
1237
596
409
1170


10000 element array; apparent problem: mild repetition
2661
6633
8864
1157
2432
6681
6995
6633
8864
1157


20000 element array; apparent problem: repetition
2432
13677
15498
3590
13677
15498
3590
13677
15498
3590


30000 element array; apparent problem: repetition
13677
15498
3590
13677
15498
3590
13677
15498
3590
13677


50000 element array; apparent problem: repetition
19089
29176
3590
29176
3590
29176
3590
29176
3590
29176


100000 element array; 32767=2^15-1 repeating;
3590
32767
32767
32767
32767
32767
32767
32767
32767
32767


200000 element array; 32767=2^15-1 repeating;
32767
32767
32767
32767
32767
32767
32767
32767
32767
32767


300000 element array; 32767=2^15-1 repeating;
32767
32767
32767
32767
32767
32767
32767
32767
32767
32767

for me. I do not know the exact problem although the randomization seems progressively worse on
larger arrays.

------------------------------------------------------------------------
[2008-07-02 11:47:39] jani@php.net

See also bug #45302

------------------------------------------------------------------------
[2008-06-18 21:26:39] pajoye@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).



------------------------------------------------------------------------
[2008-06-18 21:04:23] crrodriguez at suse dot de

What about merging a patch that circulated in @internals that made rand() and alias to mt_rand() and
be done with this ?

------------------------------------------------------------------------
[2008-06-18 19:40:10] payton2558 at googlemail dot com

Here's the shortest version. Try varying the array_fill num parameter. Lower numbers appear to
increase the randomness.

Appears problem is array_rand interfering with the random seed but please investigate further than
that as I'm certain I experienced this problem before ever using array_rand
(rand(0,count($a)-1) works in its place and doesn't trigger bug in this example). 

<?php
	
$a = array_fill(0, 100000, "word");

for ($i=0; $i<20; $i++) {
	
	array_rand($a);
	
	echo rand(1,9999)."\n";
}
?>

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


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 (#184304) next »