Laravel str_random() or custom function?

后端 未结 4 1654
伪装坚强ぢ
伪装坚强ぢ 2020-12-23 17:26

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

For example:

str_random(32);

This produces a rando

相关标签:
4条回答
  • 2020-12-23 17:51

    you can use this

    use Illuminate\Support\Str;
    
    $random = Str::random(40);
    
    0 讨论(0)
  • 2020-12-23 17:53

    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

    0 讨论(0)
  • 2020-12-23 18:01

    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. And as random_bytes became available in PHP 7 Laravel slowly shifted to use that function and uses only that without any fallback.

    The default UUID library in Laravel is ramsey/uuid. By looking at the code we can find out the default random generator is RandomBytesGenerator which uses random_bytes the same method what 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 almost the same if you would use Str::random with length equal to 16 or Uuid::uuid4 (without any modifying the randomGenerator of Uuid).

    0 讨论(0)
  • 2020-12-23 18:08

    You can use this package.

    For example:

    Uuid::generate()
    
    0 讨论(0)
提交回复
热议问题