简体   繁体   English

PHP Random String Generator…不是那么随机

[英]PHP Random String Generator… not so random

I always thought my code generated pretty random strings but I've been pressing F5 for about 10 minutes and I display 10 strings at once and I have had THREE DUPLICATES, UNIBON, ZANOPE and ZOTAXS. 我一直以为我的代码会生成相当随机的字符串,但是我一直按F5大约10分钟,并且一次显示10个字符串,并且有3个重复项,UNIBON,ZANOPE和ZOTAXS。

Can anyone explain why this is when I though there code be 26^6 possibilities? 谁能解释为什么这是我尽管有26 ^ 6种可能性的代码?

$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$pass = '';
for ($i = 0; $i < $len; $i++){
    $pass .= $chars[(rand() % strlen($chars))];
}
return $pass;

Any advice would be much appreciated. 任何建议将不胜感激。

Thanks 谢谢


Using mt_rand the first duplicate takes on average between 10 and 60 seconds, that seems okay doesn't it? 使用mt_rand,第一次复制平均需要10到60秒,这似乎还好吗?

echo 'start: '.date('H:i:s');
for ($i = 1; ; $i++) {
    $testarr[]  = passGen(6);
    $new        = passGen(6);
    if (in_array($new,$testarr)){
        echo '<br>end: '.date('H:i:s');
        echo '<br>string: '.$new;
        echo '<br>count: '.count($testarr);
        break;
    }
}

为什么不哈希一个随机数,然后从哈希中获取一个随机子串呢?

I think that's just the nature of the beast. 我认为那只是野兽的本性。 Increase the length to 7 and add some more characters and the probability of duplicates goes down. 将长度增加到7,并添加更多字符,重复的可能性降低。 This is what I used to test: 这是我用来测试的内容:

<?php
$len = 6;
# Remove characters that can be mistaken for others, I,0,L,1 and 0
$chars = 'ABCDEFGHJKMNPQRSTUVWXYZ23456789';
for ($j=0;$j<100000;$j++) {
  $pass = '';
  for ($i = 0; $i < $len; $i++){
    $pass .= $chars[(rand() % strlen($chars))];
  }
  if(isset($saved[$pass])) {
    echo "Password \"$pass\" on iteration $j has duplicate(s) from iteration(s) " . implode(',',$saved[$pass]) . "\n";
  }
  $saved[$pass][] = $j;
}
?>

Using mt_rand() vs rand() didn't change the output much 使用mt_rand()vs rand()并不会改变输出

You should try this : 您应该尝试这样:

$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $pass = '';
        $length = strlen($chars)-1;
        for ($i = 0; $i < 10; $i++){
            $randomNumber = rand(0,$length);
            $pass .= substr($chars,$randomNumber,1);
        }
        return $pass;

You should use mt_rand . 您应该使用mt_rand

mt_rand is way better than rand . mt_randrand好得多。 From the PHP manual 从PHP手册

Many random number generators of older libcs have dubious or unknown characteristics and are slow. 许多早期libcs​​的随机数生成器具有可疑或未知的特征,并且运行缓慢。 By default, PHP uses the libc random number generator with the rand() function. 默认情况下,PHP使用带有rand()函数的libc随机数生成器。 The mt_rand() function is a drop-in replacement for this. mt_rand()函数替代了此函数。 It uses a random number generator with known characteristics using the » Mersenne Twister, which will produce random numbers four times faster than what the average libc rand() provides. 它使用»Mersenne Twister使用具有已知特征的随机数生成器,该生成器将产生比libc rand()平均提供的速度快四倍的随机数。

That aside you can use this function instead to generate random strings with the length you wish ;) 除此之外,您可以使用此函数来生成具有所需长度的随机字符串;)

function random($length = 10)
{      
    $chars = 'BCDFGHJKLMNPQRSTVWXYZAEIUO';

    for ($i = 0; $i < $length; $i++)
    {
        $pass .= ($i%2) ? $chars[mt_rand(19, 25)] : $chars[mt_rand(0, 18)];
    }

    return $pass;
}

This function can be used easily to generate CAPTCHAs too ;) 此函数也可以轻松用于生成验证码;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM