Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate a random, unique, alphanumeric string?

How would it be possible to generate a random, unique string using numbers and letters for use in a verify link? Like when you create an account on a website, and it sends you an email with a link, and you have to click that link in order to verify your account

How can I generate one of those using PHP?

like image 254
Andrew Avatar asked Dec 04 '09 10:12

Andrew


People also ask

How do you generate unique random strings?

There are many ways to generate a random, unique, alphanumeric string in PHP which are given below: Using str_shuffle() Function: The str_shuffle() function is an inbuilt function in PHP and is used to randomly shuffle all the characters of a string passed to the function as a parameter.

How do you generate random unique alphanumeric strings in laravel?

If you need to generate unique random string then you can use str_random() helper of Laravel. It is very simple and you can use easily. you can easily generate random string in laravel 6, laravel 7, laravel 8 and laravel 9 version using str helper.


1 Answers

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: http://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 << $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; } 

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: http://us1.php.net/manual/en/function.openssl-random-pseudo-bytes.php#104322

like image 127
Scott Avatar answered Oct 02 '22 19:10

Scott