Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How unique a 5-digit mt_rand() number is?

Tags:

php

I am just wondering, how unique is a mt_rand() number is, if you draw 5-digits number? In the example, I tried to get a list of 500 random numbers with this function and some of them are repeated.

http://www.php.net/manual/en/function.mt-rand.php

<?php
header('Content-Type: text/plain');

$errors = array();
$uniques = array();
for($i = 0; $i < 500; ++$i)
{
    $random_code = mt_rand(10000, 99999);
    if(!in_array($random_code, $uniques))
    {
        $uniques[] = $random_code;
    }
    else
    {
        $errors[] = $random_code;
    }
}

/**
 * If you get any data in this array, it is not exactly unique
 * Run this script for few times and you may see some repeats
 */
print_r($errors);
?>

How many digits may be required to ensure that the first 500 random numbers drawn in a loop are unique?

like image 709
Bimal Poudel Avatar asked Dec 05 '22 06:12

Bimal Poudel


2 Answers

If numbers are truly random, then there's a probability that numbers will be repeated. It doesn't matter how many digits there are -- adding more digits makes it much less likely there will be a repeat, but it's always a possibility.

You're better off checking if there's a conflict, then looping until there isn't like so:

$uniques = array();
for($i = 0; $i < 500; $i++) {
    do {
        $code = mt_rand(10000, 99999);
    } while(in_array($code, $uniques));
    $uniques[] = $code
}
like image 128
Josh from Qaribou Avatar answered Dec 06 '22 20:12

Josh from Qaribou


Why not use range, shuffle, and slice?

<?php

$uniques = range(10000, 99999);
shuffle($uniques);
$uniques = array_slice($uniques, 0, 500);

print_r($uniques);

Output:

Array
(
    [0] => 91652
    [1] => 87559
    [2] => 68494
    [3] => 70561
    [4] => 16514
    [5] => 71605
    [6] => 96725
    [7] => 15908
    [8] => 14923
    [9] => 10752
    [10] => 13816
    *** truncated ***
)

This method is less expensive as it does not search the array each time to see if the item is already added or not. That said, it does make this approach less "random". More information should be provided on where these numbers are going to be used. If this is an online gambling site, this would be the worst! However if this was used in returning "lucky" numbers for a horoscope website, I think it would be fine.

Furthermore, this method could be extended, changing the shuffle method to use mt_rand (where as the original method simply used rand). It may also use openssl_random_pseudo_bytes, but that might be overkill.

like image 28
Dave Chen Avatar answered Dec 06 '22 20:12

Dave Chen