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 y
Simplifying Scotts code above by removing unnecessary loops which is slowing down badly and does not make it any more secure than calling openssl_random_pseudo_bytes just once
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
$rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
return $min + $rnd%$range;
}
function getToken($length)
{
return bin2hex(openssl_random_pseudo_bytes($length)
}
When trying to generate a random password you are trying to :
First generate a cryptographically secure set of random bytes
Second is turning those random bytes into a printable string
Now, there are multiple way to generate random bytes in php like :
$length = 32;
//PHP 7+
$bytes= random_bytes($length);
//PHP < 7
$bytes= openssl_random_pseudo_bytes($length);
Then you want to turn these random bytes into a printable string :
You can use bin2hex :
$string = bin2hex($bytes);
or base64_encode :
$string = base64_encode($bytes);
However, note that you do not control the length of the string if you use base64. You can use bin2hex to do that, using 32 bytes will turn into a 64 char string. But it will only work like so in an EVEN string.
So basically you can just do :
$length = 32;
if(PHP_VERSION>=7){
$bytes= random_bytes($length);
}else{
$bytes= openssl_random_pseudo_bytes($length);
}
$string = bin2hex($bytes);
I'm late but I'm here with some good research data based on the functions provided by Scott's answer. So I set up a Digital Ocean droplet just for this 5-day long automated test and stored the generated unique strings in a MySQL database.
During this test period, I used 5 different lengths (5, 10, 15, 20, 50) and +/-0.5 million records were inserted for each length. During my test, only the length 5 generated +/-3K duplicates out of 0.5 million and the remaining lengths didn't generate any duplicates. So we can say that if we use a length of 15 or above with Scott's functions, then we can generate highly reliable unique strings. Here is the table showing my research data:
Update: I created a simple Heroku app using these functions that returns the token as a JSON response. The app can be accessed at https://uniquestrings.herokuapp.com/api/token?length=15
I hope this helps.
Here is what I'm using on one of my projects, it's working great and it generates a UNIQUE RANDOM TOKEN:
$timestampz=time();
function generateRandomString($length = 60) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
$tokenparta = generateRandomString();
$token = $timestampz*3 . $tokenparta;
echo $token;
Please note that I multiplied the timestamp by three to create a confusion for whoever user might be wondering how this token is generated ;)
I hope it helps :)
I use this one-liner:
base64_encode(openssl_random_pseudo_bytes(3 * ($length >> 2)));
where length is the length of the desired string (divisible by 4, otherwise it gets rounded down to the nearest number divisible by 4)
Here is what I use:
md5(time() . rand());
// Creates something like 0c947c3b1047334f5bb8a3b7adc1d97b