Solved

Generating a list of unique random number with PHP

Posted on 2006-06-15
15
523 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:lollodev
  • 11
  • 4
15 Comments
 
LVL 40

Expert Comment

by:RQuadling
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:lollodev
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:RQuadling
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
 
LVL 40

Expert Comment

by:RQuadling
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:RQuadling
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:lollodev
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:RQuadling
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
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 40

Expert Comment

by:RQuadling
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:lollodev
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:
RQuadling earned 500 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:lollodev
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:RQuadling
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:RQuadling
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:RQuadling
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:RQuadling
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

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Developers of all skill levels should learn to use current best practices when developing websites. However many developers, new and old, fall into the trap of using deprecated features because this is what so many tutorials and books tell them to u…
Nothing in an HTTP request can be trusted, including HTTP headers and form data.  A form token is a tool that can be used to guard against request forgeries (CSRF).  This article shows an improved approach to form tokens, making it more difficult to…
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

708 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now