Generating unique, reliable strings in PHP

In some of my recent projects, I needed to generate unique strings in PHP. Reliability was crucial and a collision was not accepted. I did some research and at the end, I found a helpful answer here.

To test the reliability, I ran some good tests, and I found that if you use a length of 10+ with the functions provided in the linked answer above, you can create highly reliable unique strings. I generated over 500K records and I never encountered a single collision for the length of 10+. The length of 5 resulted in around 1% collisions though.

PHP > 7

If you are running PHP 7.x and up, you can acomplish the results with a single function. On older PHP versions, you will have to use a combination of two functions as discussed below. On PHP 7.x, here is the function that you can use in order to create highly reliable unique strings:

function getToken($length)
{
     $token = "";
     $codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
     $codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
     $codeAlphabet.= "0123456789";
     $max = strlen($codeAlphabet);

    for ($i=0; $i < $length; $i++) {
        $token .= $codeAlphabet[random_int(0, $max-1)];
    }

    return $token;
}

Now getToken(20) will result in a unique string with a lenth of 20 characters.

PHP < 7

On PHP versions older than 7, you can use the combination of these two functions:

function crypto_rand_secure($min, $max)
{
    $range = $max - $min;
    if ($range < 1) return $min; // not so random...
    $log = ceil(log($range, 2));
    $bytes = (int) ($log / 8) + 1; // length in bytes
    $bits = (int) $log + 1; // length in bits
    $filter = (int) (1 << $bits) - 1; // set all lower bits to 1
    do {
        $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
        $rnd = $rnd & $filter; // discard irrelevant bits
    } while ($rnd > $range);
    return $min + $rnd;
}

function getToken($length)
{
    $token = "";
    $codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    $codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
    $codeAlphabet.= "0123456789";
    $max = strlen($codeAlphabet); // edited

    for ($i=0; $i < $length; $i++) {
        $token .= $codeAlphabet[crypto_rand_secure(0, $max-1)];
    }

    return $token;
}

The usage is same. You can use getToken(20) to generate a unique, random string. I hope you will find these functions helpful. If you need an API solution, here is a simple Heroku app that I’ve created that you can use to obtain unique strings.

updated_at 21-05-2020