1

I am trying to create a 'confirmation code' for every user account created on my website and storing it in the db along with their personal information. As you can see in the example below, I tried to generate a random string factoring in the time variable, however, the string is unneccessarily long.

I would like the string to be shorter than the one produced by md5 I was wondering if there is a relatively easy way to generate 10 digit (max) alphanumeric string that has an extremely low collision rate?

What I tried:

  md5(mt_rand(10000,99999).time() . 'example@domain.com');

Output:

0dd6854dba19e70cfda0ab91595e0376
AnchovyLegend
  • 12,139
  • 38
  • 147
  • 231
  • 1
    Why are you concerned with the length of the string? What's wrong with a longer string? – tkone Jul 02 '12 at 20:05
  • If a user needs help with their account and I ask for their confirmation number, it would be easier to not have a 30+ character string, especially if they got 1 character wrong... – AnchovyLegend Jul 02 '12 at 20:06
  • 5
    @MHZ: I guess you could just use your existing MD5 string, and take the first 10 chars? – houbysoft Jul 02 '12 at 20:07
  • @houbysoft I thought about that:) Not sure if that is the best solution though... – AnchovyLegend Jul 02 '12 at 20:09
  • @MHZ: see my answer for another solution, using `openssl_random_pseudo_bytes`. – houbysoft Jul 02 '12 at 20:15
  • I'd take the first 10 chars of `md5()`. Good hash functions such as this ripple even a small change in input throughout the whole of its output, so your collision rate is effectively 1/2^40; that's pretty good. – halfer Jul 02 '12 at 20:32

5 Answers5

5

PHP provides the openssl_random_pseudo_bytes function that can be made to securely do what you want.

Do something like:

bin2hex(openssl_random_pseudo_bytes(5))

The above will give you something like e9d196aa14, for example.

Alternatively, just take the first 10 chars of your existing MD5 string.

houbysoft
  • 32,532
  • 24
  • 103
  • 156
  • This method is pretty nice. Thanks for the help! I am trying to decide if I should go with the first 10 characters of the long string generated in my initial post, or this method... – AnchovyLegend Jul 02 '12 at 20:20
  • 1
    @MHZ This is technically probably the most correct answer, but might be overkill for non-cryptographic use. Since you aren't basing security on the hash code, taking the first ten characters of MD5 is probably fine. – Jazz Jul 02 '12 at 20:22
  • 1
    Overkill in what sense? It creates a relatively short random string with negligibly low collision rates, right? Wouldn't I be better off with this method? Considering it accomplishes the task with less code:) – AnchovyLegend Jul 02 '12 at 20:27
0

This will generate you any random output string from Aa-Zz and 0-9 characters.

function genString($length) {
    $lowercase = "qwertyuiopasdfghjklzxcvbnm";
    $uppercase = "ASDFGHJKLZXCVBNMQWERTYUIOP";
    $numbers = "1234567890";
    $specialcharacters = "{}[];:,./<>?_+~!@#";
    $randomCode = "";
    mt_srand(crc32(microtime()));
    $max = strlen($lowercase) - 1;
    for ($x = 0; $x < abs($length/3); $x++) {
        $randomCode .= $lowercase{mt_rand(0, $max)};
    }
    $max = strlen($uppercase) - 1;
    for ($x = 0; $x < abs($length/3); $x++) {
        $randomCode .= $uppercase{mt_rand(0, $max)};
    }
    $max = strlen($specialcharacters) - 1;
    for ($x = 0; $x < abs($length/3); $x++) {
        $randomCode .= $specialcharacters{mt_rand(0, $max)};
    }
    $max = strlen($numbers) - 1;
    for ($x = 0; $x < abs($length/3); $x++) {
        $randomCode .= $numbers{mt_rand(0, $max)};
    }
    return str_shuffle($randomCode);
}

Usage

$str = genString(10);
classicjonesynz
  • 4,012
  • 5
  • 38
  • 78
0

I think the best way is

$random = substr(number_format(time() * rand(),0,'',''),0,10); // you can increase the digits by changing 10 to desired digit

Please check it out

Suneel Kumar
  • 5,621
  • 3
  • 31
  • 44
-1

Try using http://php.net/manual/en/function.str-split.php

Andrey
  • 849
  • 5
  • 17
  • 28