2015-08-13 79 views
1

我指的是在PHP random string generator(我已经删除了默认的$长度参数)的答案函数。PHP随机字符串其实不是随机的

因此,此代码使用该函数,但由于某种原因,如果您运行此代码,您将看到该字符串在数组中出现多次!那么,如果这是真正的随机性,我可以产生这些结果吗?我需要修改一些东西来产生真正随机的字符串吗?

function generateRandomString($length) { 
    $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; 
    $charactersLength = strlen($characters); 
    $randomString = ''; 

    for ($i = 0; $i < $length; $i++) { 
     $randomString .= $characters[rand(0, $charactersLength - 1)]; 
    } 

    return $randomString; 
} 

$i = 0; 
while ($i < 5000){ 
    $r = ''; 
    $r = generateRandomString(8); 
    $arr[$r][$i] = $r; 
    $i++; 
} 

foreach ($arr as $key=>$rand){ 
    if(count($rand) > 1){ 
     echo "$key has ".count($rand).' results<br>'; 
    } 
} 

实施例的结果:

ASCn2Db1 has 2 results 
4ceXoUgh has 2 results 
fCdzjEAV has 2 results 
QRkXxAUJ has 2 results 
+2

创建随机字符串并不意味着字符串保证是唯一的!为什么会这样呢?随机算法没有历史记录。而实际上恰恰相反:对于简短的字符串和许多尝试,你必须期待重复。只有很多可能的组合... – arkascha

+0

您正在将这些随机字符串保存在数据库中。如果是的话,你可以很容易地摆脱使用while循环的重复字符串 –

+0

真的 - 我刚才以为我们不太可能看到很多重复项 – Antony

回答

2

随机不是唯一的。投掷一个骰子,你会得到相同的数字多次..

+1

不够公平,但是在5000个循环中,并且从8个元素字符串中的61个元素中进行选择,超过900(这是我所看到的)结果的几率是多少?我会说那太高了。 – Antony

+0

人类不善于估计概率分布;) – BobbyTables

+1

在5000个循环中有900个重复项,显然不能称为随机项,无论你估计得有多糟糕。 –

-1

我记得读一篇关于这个时间前的文章,我发现it again
在这篇文章中,他让位图显示了在Windows上运行的随机函数,而不是完全随机的。

我会建议你使用mt_rand()来代替,你可以​​3210

+0

不,不要使用'mt_rand()',它和'rand()'一样坏。 http://www.openwall.com/php_mt_seed/ –

0

我提供了an answer to the question you referenced in your question,但它埋没在不安全的答案下,我并不感到惊讶,大家都错过了它。

在你的代码,是造成如此多的重复值的错误是在这里:

for ($i = 0; $i < $length; $i++) { 
    $randomString .= $characters[rand(0, $charactersLength - 1)]; 
} 

问题是rand()。如果您想要高质量的PHP random string generator,您需要使用更好的随机数发生器来为其供电。你这里有三个好选择:

  • random_int()(PHP 7+只)
  • random_compat,这在PHP 5个项目(5.2+)
  • RandomLib(PHP暴露了一个兼容接口random_int() 5.3.2+ )

TL; DR使用random_int(),never rand() or mt_rand()

即使使用安全的随机数生成器,如果您有短的字符串和足够大的样本大小,collisions are inevitable due to the birthday problem。使用更长的字符串,他们会少得多。