加快生成N个唯一随机数字的代码

问题描述:

我一直要求产生范围内所有可能的组合AA0000-ZZ9999(姑且称之为folio),每个组合我也需要一个8位数字组成唯一ramdom号(姑且称之为attcode),不能是连续的,我知道有很多的组合,过程将是缓慢的,但我使用的rand功能,我已经来验证每一个attcode必须是唯一的,它为使我的代码慢,所以如果是有可能(我知道这是,只是不知道怎么做),给我建议“回合我怎么能在我的代码改善这种加快生成N个唯一随机数字的代码

$alph = str_split("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 1); 
$code_cache = array(); 
foreach ($alph as $value1) { 
    foreach ($alph as $value2) { 
    for ($i = 0; $i <= 9; $i++) { 
     $n=$i; 
     if($i<10){ 
      $n="000".$i; 
     } 
     elseif($i<100){ 
      $n="00".$i; 
     } 
     elseif($i<1000){ 
      $n="0".$i; 
     } 
     $code = rand(10000000, 99999999); 
     while(in_array($code, $code_cache)){ 
      $code = rand(10000000, 99999999); 
     } 
     $code_cache[]=$code; 
     echo $value1.$value2.$n.'-'.$code.'<br/>'; 
    } 
    } 
} 
+1

你想要的结果实际上是每2 - “数字”基地-26追加到每一个4位数字的基数为10的数字。根据定义,这需要生成“(26^2)*(10^4)= 6,760,000”组合。这将是缓慢...... – 2012-08-03 20:56:06

+0

已经知道了,但是,如果我允许'要反复attcode',它运行的方式更快 – 2012-08-03 21:01:49

+0

我绝不能够产生所有的组合,以缓慢的过程,也许我只是需要一个更好的电脑,哈哈。 – 2012-08-03 21:05:07

好吧,我完全破解它这次。我对这个真的有些高兴,因为:

// An array of 10000 0's 
$attcodes1 = array_fill(0, 9999, 0); 

// An array of 10000 from 0 - 9999 
$attcodes2 = range(0, 9999); 
// Not actually necessary but makes $attcodes appear more random 
shuffle($attcodes2); 

// Loop until the alphas roll over to 3 characters 
for ($alpha = "AA", $num = 0; $alpha != 'AAA'; $num++) { 
    if ($num == 1001) { 
    $num = 0; // At 1000 reset the counter to 0 
    $alpha++; // Roll over to next alpha sequence 
    } 
    $folio = sprintf("$alpha%04s", $num); // Generate folio 

    // Here's the clever bit, if I do say so myself... 
    // Loop while we are hitting 4 digit sequences that have used every other 
    // possible 4 digit sequence and remove them from the options. 
    // This is *very* unlikely to loop more than twice, if ever 
    while ($attcodes1[$part1 = array_rand($attcodes1)] >= 9999) { 
    array_splice($attcodes1, $part1, 1); 
    } 
    // Get a 4 digit sequence not used with $part1 before and make sure we never 
    // get it again (increment counter) 
    $part2 = $attcodes2[$attcodes1[$part1]++]; 
    // Now it just needs stitching together and left-padding with 0s 
    $attcode = sprintf("%04s%04s", $part1, $part2); 

    // Job done 
    echo $folio.'-'.$attcode."\n"; 

} 

...和所有没有疯狂的内存使用情况我早期的尝试中产生。严重的是,它需要24字节为存储32位(4 字节!)整数在PHP。

看着我(相当低规格)笔记本电脑的进度,我估计10分钟的运行时间从开始到结束。如果你不在飞行中回应结果,这将大大减少。我认为。虽然我不确定你会用它们做什么,而不会烧毁内存或卡在磁盘I/O上。

+0

谢谢,顺便说一句,我不知道'$ alpha =“AA”'和'$ alpha ++',既没有'sprintf(“$ alpha%04s”,$ num);',大声笑,我需要阅读更多文档。 – 2012-08-05 15:40:26

我已经作出一个功能,请通过它

function fnGetRandomNumber($intLength = 6) 
{ 
    $arrAlphNumeric = array("c","d"); 
    $arrCharacters = array("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"); 
    $arrNumbers = array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9"); 
    $strNewNumber = ""; 
    $intCountNumberLength = 1; 
    do { 
    $strValue = $arrAlphNumeric[rand(0,1)]; 
    if($strValue == "c") { 
     $strNewNumber .= $arrCharacters[rand(0,25)]; 
     } else { 
     $strNewNumber .= $arrNumbers[rand(0,9)]; 
     } 
     $intCountPasswordLength++; 
    } while($intNumberLength >= $intCountNumberLength); 

    return $strNewNumber; 
}