Bug 589: make random selection slightly more random. PHP's
authorWil Mahan <wmahan@users.mediawiki.org>
Mon, 11 Oct 2004 17:34:39 +0000 (17:34 +0000)
committerWil Mahan <wmahan@users.mediawiki.org>
Mon, 11 Oct 2004 17:34:39 +0000 (17:34 +0000)
mt_rand() function has a maximum value of 2^31-1, which
is small enough that duplicate values can occur due to the
Birthday paradox, e.g. on the English Wikipedia. To fix
this, add a wfRandom() function that calls mt_rand()
twice to get the desired amount of randomness.

includes/GlobalFunctions.php
includes/SpecialRandompage.php
includes/SpecialUndelete.php
includes/Title.php

index 971e671..276a863 100644 (file)
@@ -124,6 +124,22 @@ function wfSeedRandom() {
        }
 }
 
+/**
+ * Get a random decimal value between 0 and 1, in a way
+ * not likely to give duplicate values for any realistic
+ * number of articles.
+ *
+ * @return string
+ */
+function wfRandom() {
+       # The maximum random value is "only" 2^31-1, so get two random
+       # values to reduce the chance of dupes
+       $max = mt_getrandmax();
+       $rand = number_format( mt_rand() * mt_rand()
+               / $max / $max, 12, '.', '' );
+       return $rand;
+}
+
 /**
  * We want / and : to be included as literal characters in our title URLs.
  * %2F in the page titles seems to fatally break for some reason.
index a8c5ed3..4066c65 100644 (file)
@@ -20,10 +20,9 @@ function wfSpecialRandompage() {
        #
        # Using a literal constant means the whole thing gets optimized on
        # the index, and the comparison is both fast and fair.
-       $rand = mt_rand() / mt_getrandmax();
        
        # interpolation and sprintf() can muck up with locale-specific decimal separator
-       $randstr = number_format( $rand, 12, ".", "" );
+       $randstr = wfRandom();
        
        $db =& wfGetDB( DB_SLAVE );
        $use_index = $db->useIndexClause( 'cur_random' );
index 3e4e2d9..0252760 100644 (file)
@@ -167,7 +167,7 @@ class PageArchive {
                        $redirect = MagicWord::get( MAG_REDIRECT );
                        $redir = $redirect->matchStart( $text ) ? 1 : 0;
                        
-                       $rand = number_format( mt_rand() / mt_getrandmax(), 12, '.', '' );
+                       $rand = wfRandom();
                        $dbw->insertArray( 'cur', array(
                                'cur_id' => $dbw->nextSequenceValue( 'cur_cur_id_seq' ),
                                'cur_namespace' => $namespace,
index 9eb2552..ef11553 100644 (file)
@@ -1441,7 +1441,7 @@ class Title {
                $now = $dbw->timestamp();
                $won = wfInvertTimestamp( wfTimestamp(TS_MW,$now) );
                wfSeedRandom();
-               $rand = number_format( mt_rand() / mt_getrandmax(), 12, '.', '' );
+               $rand = wfRandom();
 
                # Rename cur entry
                $dbw->updateArray( 'cur',