Generating a list of unique random number with PHP

Hi,

I would like to generate a list of 500,000 unique random numbers that will be printed on coupons.
The numbers it generates must have a prefix "MLX" before a 9 digit number (MLX846795265).

How can I produce this list of unique random numbers and print all 500,000 numbers on a .TXT file

I found this script that seems to partially do the job.  How can I modify it to print 500,000 unique numbers on a text file?

Please let me know.

Thanks,
-L.


<?
function generateRandomNumber($digits){

$characters = "0123456789";
$returnValue = "";

for($no=0;$no<$digits;$no++){

$randValue = mt_rand(0,(strlen($characters)-1));
$returnValue.=substr($characters,$randValue,1);
}

return $returnValue;
}

echo "MLX".generateRandomNumber(9);

?>
Laurent BelinAsked:
Who is Participating?
 
Richard QuadlingConnect With a Mentor Senior Software DeveloperCommented:
Doh. Of course you would! Sorry. I tend to return true/false from most of my functions.

<?php
// Allow the script to run forever.
set_time_limit(0);

function generateRandomNumbers($i_number_of_digits, $i_number_of_results)
      {
      $a_results = array();
      $i_max = (int)str_repeat('9', $i_number_of_digits);
      while (count($a_results) !== $i_number_of_results)
            {
            $a_results['MLX' . str_pad(rand(1, $i_max), $i_number_of_digits, '0', STR_PAD_LEFT)] = count($a_results);
            }
      return array_flip($a_results);
      }

$fp = fopen('./random.txt', 'wt');
foreach(generateRandomNumbers(9, 50) as $s_random_value)
      {
      fwrite($fp, "$s_random_value\n");
      }
fclose($fp);
?>
0
 
Richard QuadlingSenior Software DeveloperCommented:
<?php

function generateRandomNumbers($i_number_of_digits, $i_number_of_results, &$a_results)
      {
      $a_results = array();
      $i_max = (int)str_repeat('9', $i_number_of_digits);
      while ($i_number_of_results !== 0)
            {
            $i_random_value = str_pad(rand(1, $i_max), $i_number_of_digits, '0', STR_PAD_LEFT);
            if (!in_array($i_random_value, $a_results))
                  {
                  $a_results[] = $i_random_value;
                  $i_number_of_results--;
                  }
            }
      }

generateRandomNumbers(9, 100, $a_random_numbers);
print_r($a_random_numbers);
echo count($a_random_numbers) . "\n";
echo count(array_unique($a_random_numbers)) . "\n";
?>

generates output of ...

Array
(
    [0] => 256866455
    [1] => 484558105
    [2] => 849822998
    [3] => 273071289
    [4] => 829010009
    [5] => 410705566
    [6] => 112396241
    [7] => 956054687
    [8] => 086700440
    [9] => 061462403
    [10] => 357391358
    [11] => 723022461
    [12] => 498687744
    [13] => 530578613
    [14] => 803558349
    [15] => 417724609
    [16] => 033721924
    [17] => 411804199
    [18] => 169647217
    [19] => 383911133
    [20] => 160552979
    [21] => 798889160
    [22] => 674407959
    [23] => 465332031
    [24] => 847930908
    [25] => 285583496
    [26] => 036590577
    [27] => 005737305
    [28] => 564605713
    [29] => 965637207
    [30] => 474945068
    [31] => 848876953
    [32] => 279327393
    [33] => 432800293
    [34] => 708221435
    [35] => 338500977
    [36] => 460845947
    [37] => 780822754
    [38] => 955169677
    [39] => 318359375
    [40] => 077911377
    [41] => 603454590
    [42] => 934539794
    [43] => 132202149
    [44] => 599273682
    [45] => 994445800
    [46] => 865081787
    [47] => 623779297
    [48] => 993682861
    [49] => 547546387
    [50] => 465545654
    [51] => 136840821
    [52] => 729888916
    [53] => 356506348
    [54] => 954681396
    [55] => 515136719
    [56] => 776641845
    [57] => 015075684
    [58] => 051239014
    [59] => 102416993
    [60] => 602691650
    [61] => 617004394
    [62] => 973968505
    [63] => 742431640
    [64] => 176788330
    [65] => 756042480
    [66] => 441619873
    [67] => 778930664
    [68] => 967681884
    [69] => 525939941
    [70] => 672943115
    [71] => 055664063
    [72] => 944122314
    [73] => 520446777
    [74] => 386688233
    [75] => 916381836
    [76] => 574859619
    [77] => 833312988
    [78] => 801605224
    [79] => 204833985
    [80] => 828643798
    [81] => 058288575
    [82] => 636444092
    [83] => 264770508
    [84] => 174224854
    [85] => 289123535
    [86] => 109954834
    [87] => 939941406
    [88] => 580352783
    [89] => 119567871
    [90] => 940887451
    [91] => 574096680
    [92] => 515777588
    [93] => 643371582
    [94] => 347991944
    [95] => 010986329
    [96] => 949249267
    [97] => 454284668
    [98] => 050018311
    [99] => 594360351
)
100
100
0
 
Laurent BelinAuthor Commented:
Hi RQuadling ,

Thanks for your response.  
I tried your script and it works up until 10,000 unique numers but I can't manage to generate 500,000 numbers. I tried with the set_time_limit() function but it will still go in time-out.

My other question was on how to print the numbers with the "MLX" prefix on a txt file.

Please let me know.

<?php
set_time_limit(300);
function generateRandomNumbers($i_number_of_digits, $i_number_of_results, &$a_results){
$a_results = array();
$i_max = (int)str_repeat('9', $i_number_of_digits);
while ($i_number_of_results !== 0)
{
$i_random_value = str_pad(rand(1, $i_max), $i_number_of_digits, '0', STR_PAD_LEFT);
if (!in_array($i_random_value, $a_results))
{
$a_results[] = $i_random_value;
$i_number_of_results--;
}
}
}

generateRandomNumbers(9, 500000, $a_random_numbers);
print_r($a_random_numbers);
echo count($a_random_numbers) . "\n";
echo count(array_unique($a_random_numbers)) . "\n";
?>
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
Richard QuadlingSenior Software DeveloperCommented:
Sorry.

<?php
// Allow the script to run forever.
set_time_limit(0);

function generateRandomNumbers($i_number_of_digits, $i_number_of_results, &$a_results)
      {
      $a_results = array();
      $i_max = (int)str_repeat('9', $i_number_of_digits);
      while ($i_number_of_results !== 0)
            {
            $i_random_value = 'MLX' . str_pad(rand(1, $i_max), $i_number_of_digits, '0', STR_PAD_LEFT);
            if (!in_array($i_random_value, $a_results))
                  {
                  $a_results[] = $i_random_value;
                  $i_number_of_results--;
                  }
            }
      }

generateRandomNumbers(9, 500000, $a_random_numbers);
echo count($a_random_numbers) . "\n";
echo count(array_unique($a_random_numbers)) . "\n";
?>

Takes a while.
0
 
Richard QuadlingSenior Software DeveloperCommented:
This may be faster ...

function generateRandomNumbers($i_number_of_digits, $i_number_of_results, &$a_results)
      {
      $a_results = array();
      $i_max = (int)str_repeat('9', $i_number_of_digits);
      while (count($a_results) !== $i_number_of_results)
            {
            $a_results['MLX' . str_pad(rand(1, $i_max), $i_number_of_digits, '0', STR_PAD_LEFT)] = count($a_results);
            }
      $a_results = array_keys($a_results);
      }

I'm currently testing this. Old code has taken 10 minutes and counting.
0
 
Richard QuadlingSenior Software DeveloperCommented:
It seems that the second method is faster over 1000 but at 5000 the first method was faster.

So, try both. See which you prefer. If speed is not an issue then I suppose it doesn't matter.
0
 
Laurent BelinAuthor Commented:
I'm still testing the first method.  Can't manage to have the second one working...but time isn't an issue anyways.

How can I print the numbers to a txt file without the array brackets (Array ( [0] =>) ?

Thanks,
-L.
0
 
Richard QuadlingSenior Software DeveloperCommented:
Change

generateRandomNumbers(9, 500000, $a_random_numbers);

to ...

(PHP5)
foreach(generateRandomNumbers(9, 500000, $a_random_numbers) as $s_random_value)
 {
 file_put_contents('./random.txt', "$s_random_value\n", FILE_APPEND);
 }

(PHP4)
$fp = fopen('./random.txt', 'wt');
foreach(generateRandomNumbers(9, 500000, $a_random_numbers) as $s_random_value)
 {
 fwrite($fp, "$s_random_value\n");
 }
fclose($fp);


0
 
Richard QuadlingSenior Software DeveloperCommented:
If you are running this from the command line, then you could use ...

foreach(generateRandomNumbers(9, 500000, $a_random_numbers) as $s_random_value)
 {
 echo "$s_random_value\n";
 }


and capture the output using normal shell redirection ...

php random.php > random.txt
0
 
Laurent BelinAuthor Commented:
I get an error on the foreach statement.
I'm still running the first script....hope it is almost over.

<?php
// Allow the script to run forever.
set_time_limit(0);


function generateRandomNumbers($i_number_of_digits, $i_number_of_results, &$a_results)

{
$a_results = array();
$i_max = (int)str_repeat('9', $i_number_of_digits);
while ($i_number_of_results !== 0)
{
$i_random_value = 'MLX' . str_pad(rand(1, $i_max), $i_number_of_digits, '0', STR_PAD_LEFT);
if (!in_array($i_random_value, $a_results))
{
$a_results[] = $i_random_value;
$i_number_of_results--;
}
}
}
$fp = fopen('./random.txt', 'wt');

foreach(generateRandomNumbers(9, 50, $a_random_numbers) as $s_random_value)
{
fwrite($fp, "$s_random_value\n");
}
fclose($fp);
?>
0
 
Laurent BelinAuthor Commented:
Beautiful!  

I run the script for 500,000 and in about 45 seconds it printed 499,894 unique numbers!

Just out of curiosity, why doesn't it print exactly 500.000 numbers?  This is not an issue, I'm just curious to understand.

Thanks,
-L.
0
 
Richard QuadlingSenior Software DeveloperCommented:
Really?

It should have done!!!!

And 45 seconds! WOW! What are you running on? 50,000 is taking ages on mine.

Ah. I added some debugging.

The second version hangs dead at 32768 entries.

Ah. On Windows, rand is limited to 32768. DOH.

Use mt_rand instead.

Now. My random numbers are generated and saved in around 13 seconds. Hey! That's better.
0
 
Richard QuadlingSenior Software DeveloperCommented:
Right. Some tests.

The second method is CONSIDERABLY faster than the first as only the keys are checked.

<?php
// Allow the script to run forever.
set_time_limit(0);

function generateRandomNumbers($i_number_of_digits, $i_number_of_results)
      {
      $a_results = array();
      $i_max = (int)str_repeat('9', $i_number_of_digits);
      $i_count = $i_number_of_results;
      while (count($a_results) !== $i_number_of_results)
            {
            $s_random = 'MLX' . str_pad(mt_rand(1, $i_max), $i_number_of_digits, '0', STR_PAD_LEFT);
            if (!isset($a_results[$s_random]))
                  {
                  $a_results[$s_random] = $i_count--;
                  }
            }
      return array_flip($a_results);
      }

$fp = fopen('./random.txt', 'wt');
$s_output = implode("\n", generateRandomNumbers(9, 500000));
fwrite($fp, $s_output);
fclose($fp);
?>

0
 
Richard QuadlingSenior Software DeveloperCommented:
In my tests, EXACTLY 500,000 unique lines were outputted. I can see no reason why the file is not right. Try the new code above to see if this is any better for you.
0
 
Richard QuadlingSenior Software DeveloperCommented:
Also, rand produced 32768 random values before duplicating. mt_rand will produce duplicate answers but these are rejected using the code.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.