2

I know the uniqid() method to create lots of unique ids with a length of 7 or more, but what I want to create is a length of 5 unique id with no collision.

Is it possible to create 220.000 unique id's with a length of 5 and check if there is any collision?

Pang
  • 9,564
  • 146
  • 81
  • 122
supersize
  • 13,764
  • 18
  • 74
  • 133
  • sorry but letters and numbers should be able to create more than 220.00 unique ids or not? – supersize Mar 04 '13 at 09:26
  • Realized that after I've submitted. I always see ID's as `int` :) – Mihai Iorga Mar 04 '13 at 09:28
  • 4
    Assuming you take the english alphabet (26 characters) and numeric characters 0-9 we have a total of 36 characters. The number of unique combinations is then given by 36^5 = 60466176 So this should be more than enough – Pankrates Mar 04 '13 at 09:30
  • great! and how to do that :-/ – supersize Mar 04 '13 at 09:31
  • For an example method, see this answer http://stackoverflow.com/questions/48124/generating-pseudorandom-alpha-numeric-strings – Pankrates Mar 04 '13 at 09:35
  • 2
    Maybe http://codepad.org/slExXQLQ ? – Mihai Iorga Mar 04 '13 at 09:41
  • pankrates, that looks pretty good but i have the fear this could be very slow if its checking the whole array on every number if its collisioned. but very good answer, thanks for that! – supersize Mar 04 '13 at 09:53
  • @TedMosby that is not a good example because it uses `rand` – Baba Mar 04 '13 at 10:03
  • whats wrong with rand? hes checking if there is a collision within the array... should do what i want huh? – supersize Mar 04 '13 at 10:18
  • @Baba fyi, `str_shuffle()` implicitly uses `rand()` too :) – Ja͢ck Mar 04 '13 at 10:26
  • Out of curiosity, why would you need or use a feature where you have to create unique string using PHP, and not using inbuilt functions like uniqid? – N.B. Mar 04 '13 at 10:28
  • @Jack yes i know that i why `mt_rand` was used instead ... the `str_shuffle` was to re arrange the string every time the function is called to reduce collision – Baba Mar 04 '13 at 10:56
  • @Baba I somehow doubt it does anything to reduce collision :) – Ja͢ck Mar 04 '13 at 11:56
  • @Jack did some simple test and i think and feeling lucky about add that there .. – Baba Mar 04 '13 at 13:35

3 Answers3

7

You can try

for($i = 0; $i < 10 ; $i++)
{
    echo randString(5),PHP_EOL ;
}

Output

7fh96
G93fd
97Q7E
90Wku
7Vby9
4678f
S11oe
67688
19D36
KC1bQ

Simple Collision Test

$hash = array();
$collision = 0;
while ( count($hash) < 220000 ) {
    $r = randString(5);
    if (isset($hash[$r])) {
        $collision ++;
        continue;
    }
    $hash[$r] = 1;
}

print(($collision / 220000)  * 100 . "% - ($collision)");

Tested 100,000 times and always collision is always less that 0.02 which makes the function efficient for a 5 character set

0.011818181818182% - (26)

Function Used

function randString($length) {
    $char = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    $char = str_shuffle($char);
    for($i = 0, $rand = '', $l = strlen($char) - 1; $i < $length; $i ++) {
        $rand .= $char{mt_rand(0, $l)};
    }
    return $rand;
}
Baba
  • 94,024
  • 28
  • 166
  • 217
  • 2
    these is not collision free, so you could store them as array keys and do this till your array have 220.000 keys – JaMaBing Mar 04 '13 at 09:48
  • @JaMaBing a quick test shows that the function show about `0.1181` collision .. that can be easy resolved if the has are stored see http://codepad.viper-7.com/S0W8U1 – Baba Mar 04 '13 at 09:55
  • I know, but he dont ask for random strings. So if he implemented your solution without collision detection, he get in trouble later. – JaMaBing Mar 04 '13 at 09:59
  • `is it possible to create 220.000 unique id's with a length of 5 and check if there is any collision.` he already intends to check for collision – Baba Mar 04 '13 at 10:01
  • well i thought its better to check if there is any collision. of course i would prefer a way where no collision check is needed. anyways, i will try your code snippet and thanks for that, looks quite good for me! :) – supersize Mar 04 '13 at 10:11
  • 1
    @TedMosby Not having a collision detection is of course impossible; based on your alphabet size and number of codes you need, the probability is at least 0.024%. The [birthday attack](http://en.wikipedia.org/wiki/Birthday_attack) makes the odds even better. – Ja͢ck Mar 04 '13 at 10:21
1

Take a look at this article

It explains how to generate short unique ids from your bdd ids, like youtube does.

Actually, the function in the article is very related to php function base_convert which converts a number from a base to another (but is only up to base 36).

httpete
  • 5,875
  • 4
  • 32
  • 41
0

I wanted to use uniqid() function for making a string of particular length. Hence I experimented and came up with the following code:

<?php
    $number = uniqid();
    $varray = str_split($number);
    $len = sizeof($varray);
    $otp = array_slice($varray, $len-5, $len);
    $otp = implode(",", $otp);
    $otp = str_replace(',', '', $otp);
    print_r($otp);
?>

This works fine for me, as long as your site doesn't generate OTPs at a very fast rate, this should work fine!

rollstuhlfahrer
  • 3,988
  • 9
  • 25
  • 38
Neel Bhave
  • 89
  • 1
  • 2
  • 10