?
Solved

Generating a list of unique random number with PHP

Posted on 2006-06-15
15
Medium Priority
?
548 Views
Last Modified: 2008-03-17
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);

?>
0
Comment
Question by:Laurent Belin
  • 11
  • 4
15 Comments
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 16910091
<?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
 

Author Comment

by:Laurent Belin
ID: 16911119
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
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 16911168
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 40

Expert Comment

by:Richard Quadling
ID: 16911233
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
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 16911365
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
 

Author Comment

by:Laurent Belin
ID: 16911467
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
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 16911499
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
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 16911506
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
 

Author Comment

by:Laurent Belin
ID: 16911690
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
 
LVL 40

Accepted Solution

by:
Richard Quadling earned 2000 total points
ID: 16911856
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
 

Author Comment

by:Laurent Belin
ID: 16912229
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
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 16918695
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
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 16918716
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
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 16918719
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
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 16918728
Also, rand produced 32768 random values before duplicating. mt_rand will produce duplicate answers but these are rejected using the code.
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I imagine that there are some, like me, who require a way of getting currency exchange rates for implementation in web project from time to time, so I thought I would share a solution that I have developed for this purpose. It turns out that Yaho…
This holiday season, we’re giving away the gift of knowledge—tech knowledge, that is. Keep reading to see what hacks, tips, and trends we have wrapped and waiting for you under the tree.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
Suggested Courses
Course of the Month13 days, 18 hours left to enroll

807 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question