How to generate a random unique alphanumeric string in php?

PHP 7 standard library provides the random_bytes[$length] function that generate cryptographically secure pseudo-random bytes.

Example:

$bytes = random_bytes[20];
var_dump[bin2hex[$bytes]];

The above example will output something similar to:

string[40] "5fe69c95ed70a9869d9f9af7d8400a6673bb9ce9"

More info: //php.net/manual/en/function.random-bytes.php

PHP 5 [outdated]

I was just looking into how to solve this same problem, but I also want my function to create a token that can be used for password retrieval as well. This means that I need to limit the ability of the token to be guessed. Because uniqid is based on the time, and according to php.net "the return value is little different from microtime[]", uniqid does not meet the criteria. PHP recommends using openssl_random_pseudo_bytes[] instead to generate cryptographically secure tokens.

A quick, short and to the point answer is:

bin2hex[openssl_random_pseudo_bytes[$bytes]]

which will generate a random string of alphanumeric characters of length = $bytes * 2. Unfortunately this only has an alphabet of [a-f][0-9], but it works.

Below is the strongest function I could make that satisfies the criteria [This is an implemented version of Erik's answer].

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  $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;
}

crypto_rand_secure[$min, $max] works as a drop in replacement for rand[] or mt_rand. It uses openssl_random_pseudo_bytes to help create a random number between $min and $max.

getToken[$length] creates an alphabet to use within the token and then creates a string of length $length.

Source: //us1.php.net/manual/en/function.openssl-random-pseudo-bytes.php#104322

gagarine

3,9632 gold badges29 silver badges39 bronze badges

answered Dec 5, 2012 at 22:25

ScottScott

11.7k4 gold badges26 silver badges48 bronze badges

30

Security Notice: This solution should not be used in situations where the quality of your randomness can affect the security of an application. In particular, rand[] and uniqid[] are not cryptographically secure random number generators. See Scott's answer for a secure alternative.

If you do not need it to be absolutely unique over time:

md5[uniqid[rand[], true]]

Otherwise [given you have already determined a unique login for your user]:

md5[uniqid[$your_user_login, true]]

answered Dec 4, 2009 at 10:55

loletechloletech

3,6521 gold badge14 silver badges3 bronze badges

6

Object-oriented version of the most up-voted solution

I've created an object-oriented solution based on Scott's answer:

Chủ Đề