1

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.

Can anyone explain why this is when I though there code be 26^6 possibilities?

$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?

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;
    }
}
11
  • 1
    You get the same three duplicates repeatedly? lol... Commented Mar 28, 2012 at 14:26
  • 2
    Maybe try rand(0,strlen($chars)) Commented Mar 28, 2012 at 14:28
  • 1
    for ($i = 0; $i < $len; $i++){ where do you define $len ? Commented Mar 28, 2012 at 14:29
  • I've now added rand(0,strlen($chars)) I'm just trying to create a unique name for a company as all ideas that have been put forward to the MD have been rejected lol Commented Mar 28, 2012 at 14:32
  • 3
    If you're using PHP4 or PHP5, you should be able to use mt_rand() to get a better random number as rand() is known to have problems per the PHP manual. see (php.net/manual/en/function.mt-rand.php) Commented Mar 28, 2012 at 14:34

4 Answers 4

1

Why don't you hash a random number then take a random substring from the hash?

Sign up to request clarification or add additional context in comments.

1 Comment

Not a bad idea, I'm going to see how long it takes PHP to create a duplicate with mt_rand and if it's too quick then I'll try your method, thanks
0

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;

Comments

0

You should use mt_rand.

mt_rand is way better than rand. From the PHP manual

Many random number generators of older libcs have dubious or unknown characteristics and are slow. By default, PHP uses the libc random number generator with the rand() function. The mt_rand() function is a drop-in replacement for this. 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.

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 ;)

3 Comments

What is the idea of grouping the alphabet ($chars), and why don't you use the whole alphabet (0-25)? It will reduce the possible combinations.
@martinstoeckli sorry my bad (^^,) I forgot to rearrange the alphabet to work for the example. I usually arrange the letters in certain order to create easily pronounceable words (i.e. constant, vowel,constant,vowel,...etc.)
@Songo if you don't mind archaic words, a sentence with 26 letters: "Cwm fjord bank glyphs vext quiz."
0

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. 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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.