PHP随机字符串实际上并不随机

时间:2015-08-13 09:39:44

标签: php random

我指的是PHP random string generator上答案中的函数(我删除了默认的$ length参数)。

所以这段代码使用了这个函数,但是出于某种原因,如果你运行这段代码,你会看到字符串在数组中多次出现!那么,如果这是真正随机的,我可以产生这些结果吗?我是否需要修改某些内容以生成非常随机的字符串?

function generateRandomString($length) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $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

4 个答案:

答案 0 :(得分:2)

随机并非唯一。扔一个骰子,你会多次获得相同的数字..

答案 1 :(得分:0)

我实际上遇到PHP: How to generate a random, unique, alphanumeric string?似乎回答了我的问题。简而言之,我们使用openssl_random_pseudo_bytes作为函数。当用4个字符运行时,我得到了1次碰撞但是在5个字符上我没有产生任何碰撞。所以对于8我应该没事。

答案 2 :(得分: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项目中展示random_int()的兼容接口(5.2 +)
  • RandomLib(PHP 5.3.2 +)

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

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

答案 3 :(得分:-1)

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

我建议你改用mt_rand(),你可以read more about the mt_rand() here

相关问题