'Laravel str_random() or custom function?

Is the Laravel str_random() function random enough so that I can use it for IDs?

For example:

str_random(32);

This produces a random string of length 32 made up of alphanumeric characters [a-zA-z0-9] (62 characters in total).

Which equates to 2272657884496751345355241563627544170162852933518655225856 possibilities.

However, my question is, is this going to be good enough? Or should I consider using UUIDs or another custom function.



Solution 1:[1]

str_random (Str::random()) tries to use openssl_random_pseudo_bytes which is a pseudo random number generator optimized for cryptography, not uniqueness. If openssl_random_pseudo_bytes is not available, it falls back to quickRandom():

public static function quickRandom($length = 16)
{
    $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

    return substr(str_shuffle(str_repeat($pool, 5)), 0, $length);
}

In my opinion quickRandom code is not reliable for uniqueness nor cryptography.

Yes, having openssl_random_pseudo_bytes and using 32 bytes is almost impossible to see a collision, but it's still possible. If you want to make sure your strings/numbers will be unique (99.99%), you better use a UUID function. This is what I normally use:

/**
 * 
 * Generate v4 UUID
 * 
 * Version 4 UUIDs are pseudo-random.
 */
public static function v4() 
{
    return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',

    // 32 bits for "time_low"
    mt_rand(0, 0xffff), mt_rand(0, 0xffff),

    // 16 bits for "time_mid"
    mt_rand(0, 0xffff),

    // 16 bits for "time_hi_and_version",
    // four most significant bits holds version number 4
    mt_rand(0, 0x0fff) | 0x4000,

    // 16 bits, 8 bits for "clk_seq_hi_res",
    // 8 bits for "clk_seq_low",
    // two most significant bits holds zero and one for variant DCE1.1
    mt_rand(0, 0x3fff) | 0x8000,

    // 48 bits for "node"
    mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
    );
}

It generates a VALID RFC 4211 COMPLIANT version 4 UUID.

Check this: https://en.wikipedia.org/wiki/Universally_unique_identifier#Collisions

Solution 2:[2]

you can use this

use Illuminate\Support\Str;

$random = Str::random(40);

Solution 3:[3]

The accepted answer was true in April of 2014. It is not accurate anymore. In November of 2014 there was a commit which removed the use of quickRandom. As random_bytes became available in PHP 7 Laravel slowly shifted to that function and uses that one only without any fallback.

ramsey/uuid is the default UUID library in Laravel. By looking at the code we can find out the default random generator is RandomBytesGenerator which uses random_bytes. The same method Str::random uses.

The Wikipedia page about UUID states the following about UUID v4:

[...] version-4 UUID will have 6 predetermined variant and version bits, leaving 122 bits for the randomly generated part, [...]

https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)

128 bits = 122 random bits + 6 version bits. 128 bits is exactly 16 bytes. Most of the UUID implementations reads 16 bytes of random bytes and then replaces the version at the specified position (in case of v4).

All in all, as of now it is almost the same if you would use Str::random with length equal to 16 or Uuid::uuid4 (without modifying the randomGenerator of Uuid).

Solution 4:[4]

To make it more unique use TIMESTAMP and concat row id with it simple and zero possibility to repeat number

Solution 5:[5]

You can use this package.

For example:

Uuid::generate()

Solution 6:[6]

I'm using Laravel 6 version, on that Illuminate\Support\Str::random works well however neither str_random nor Illuminate\Support\Str::str_random works for me using Laravel 6.

Bellow you can see the function's documentation

/**
* Generate a more truly "random" alpha-numeric string.
*
* @param  int  $length
* @return string
*/
public static function random($length = 16)

Solution 7:[7]

the easier one is:

$random = str_random(3).substr(time(), 6,8).str_random(3);

It will generate a 10 digit true unique number.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Nergal
Solution 2 hashem sheikhypour
Solution 3
Solution 4 hu7sy
Solution 5 double-beep
Solution 6 Lucas Guimaraes
Solution 7 Abdur Rahim