views:

96

answers:

2

Hi guys!!

I need to generate a string using PHP, it need to be unique and need to be from 4 to 8 characters (the value of a variable).

I thought I can use crc32 hash but I can't decide how many characters, but sure it will be unique. In the other hand only create a "password generator" will generate duplicated string and checking the value in the table for each string will take a while.

How can I do that?

Thanks!


Maybe I can use that :

  function unique_id(){
  $better_token = md5(uniqid(rand(), true));
  $unique_code = substr($better_token, 16);
  $uniqueid = $unique_code;
  return $uniqueid;
  }

  $id = unique_id();

Changing to :

  function unique_id($l = 8){
  $better_token = md5(uniqid(rand(), true));
      $rem = strlen($better_token)-$l;
  $unique_code = substr($better_token, 0, -$rem);
  $uniqueid = $unique_code;
  return $uniqueid;
  }

  echo unique_id(4);

Do you think I'll get unique string each time for a goood while?

+2  A: 

The problem with randomness is that you can never be sure of anything. There is a small chance you could get one number this time and the same number the next. That said, you would want to make the string as long as possible to reduce that probability. As an example of how long such numbers can be, GUIDs (globally unique identifiers) are 16 bytes long.

In theory, four hex characters (16 bits) give only 16^4 = 65536 possibilities, while eight hex characters (32 bits) give 16^8 = 4294967296. You, however, need to consider how likely it is for any two hashes to collide (the "birthday problem"). Wikipedia has a good table on how likely such a collision is. In short, four hex characters are definitely not sufficient, and eight might not be.

You may want to consider using Base64 encoding rather than hex digits; that way, you can fit 48 bits in rather than just 32 bits.

Eight bytes is 8 * 8 = 64 bits.

idealmachine
@Idealmachine: Yeah but how I can Generate base64 ? The only thing I know about Base64, is that I can convert mp3 and images into strings and Firefox will show them :P (And thanks for the math course! I loove maths! XD {Really!})
Jeremy Dicaire
Actually, looking at the code you posted more closely, you already are using md5 with the raw_output option, so I assume that your application is OK with any character from ASCII 0 to 255 (**including** null bytes). If that is in fact a problem though, then you could take the first six bytes of the MD5 and then base64_encode() them.
idealmachine
Okay thank you I'll take a deeper look at this tomorrow :)
Jeremy Dicaire
+1  A: 

In short, I think you'll get a pretty good random value. There's always the chance of a collision but you've done everything you can to get a random value. uniqid() returns a random value based on the current time in microseconds. Specifying rand() (mt_rand() would be better) and the second argument as true to uniqid() should make the value even more unique. Hashing the value using md5() should also make it pretty unique as even a small difference in two random values generated should be magnified by the hashing function. idealmachine is correct in that a longer value is less likely to have a collision than a shorter one.

Your function could also be shorter since md5() will always return a 32 character long string. Try this:

function unique_id($l = 8) {
    return substr(md5(uniqid(mt_rand(), true)), 0, $l);
}
Jeremy
Wow! Thanks :) I appreciate! I feel a little smarter :D And thanks for the shorter code! You make my life easier :) AND WE HAVE THE SAME NAME! WOW! I owe you a beer for that! ;)
Jeremy Dicaire
I never even noticed we had the same name until you mentioned it :-). If you think my answer solves your question could you mark it as the accepted answer? Thanks.
Jeremy
LOL Sorry Jay I'm very buse these days, I got a new job and it take me much of times :) .. Marked! You want your reputations points? :P I also vite it up :) Have a nice evening!
Jeremy Dicaire
Thanks! I appreciate it.
Jeremy
Your welcome, it's the only thing I can do to thanks you :)
Jeremy Dicaire