PHP function to generate v4 UUID

前端 未结 15 1082
眼角桃花
眼角桃花 2020-11-22 03:01

So I\'ve been doing some digging around and I\'ve been trying to piece together a function that generates a valid v4 UUID in PHP. This is the closest I\'ve been able to come

相关标签:
15条回答
  • 2020-11-22 03:53

    My answer is based on comment uniqid user comment but it uses openssl_random_pseudo_bytes function to generate random string instead of reading from /dev/urandom

    function guid()
    {
        $randomString = openssl_random_pseudo_bytes(16);
        $time_low = bin2hex(substr($randomString, 0, 4));
        $time_mid = bin2hex(substr($randomString, 4, 2));
        $time_hi_and_version = bin2hex(substr($randomString, 6, 2));
        $clock_seq_hi_and_reserved = bin2hex(substr($randomString, 8, 2));
        $node = bin2hex(substr($randomString, 10, 6));
    
        /**
         * Set the four most significant bits (bits 12 through 15) of the
         * time_hi_and_version field to the 4-bit version number from
         * Section 4.1.3.
         * @see http://tools.ietf.org/html/rfc4122#section-4.1.3
        */
        $time_hi_and_version = hexdec($time_hi_and_version);
        $time_hi_and_version = $time_hi_and_version >> 4;
        $time_hi_and_version = $time_hi_and_version | 0x4000;
    
        /**
         * Set the two most significant bits (bits 6 and 7) of the
         * clock_seq_hi_and_reserved to zero and one, respectively.
         */
        $clock_seq_hi_and_reserved = hexdec($clock_seq_hi_and_reserved);
        $clock_seq_hi_and_reserved = $clock_seq_hi_and_reserved >> 2;
        $clock_seq_hi_and_reserved = $clock_seq_hi_and_reserved | 0x8000;
    
        return sprintf('%08s-%04s-%04x-%04x-%012s', $time_low, $time_mid, $time_hi_and_version, $clock_seq_hi_and_reserved, $node);
    } // guid
    
    0 讨论(0)
  • 2020-11-22 03:55

    Instead of breaking it down into individual fields, it's easier to generate a random block of data and change the individual byte positions. You should also use a better random number generator than mt_rand().

    According to RFC 4122 - Section 4.4, you need to change these fields:

    1. time_hi_and_version (bits 4-7 of 7th octet),
    2. clock_seq_hi_and_reserved (bit 6 & 7 of 9th octet)

    All of the other 122 bits should be sufficiently random.

    The following approach generates 128 bits of random data using openssl_random_pseudo_bytes(), makes the permutations on the octets and then uses bin2hex() and vsprintf() to do the final formatting.

    function guidv4($data)
    {
        assert(strlen($data) == 16);
    
        $data[6] = chr(ord($data[6]) & 0x0f | 0x40); // set version to 0100
        $data[8] = chr(ord($data[8]) & 0x3f | 0x80); // set bits 6-7 to 10
    
        return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
    }
    
    echo guidv4(openssl_random_pseudo_bytes(16));
    

    With PHP 7, generating random byte sequences is even simpler using random_bytes():

    function guidv4($data = null)
    {
        $data = $data ?? random_bytes(16);
        // ...
    }
    
    0 讨论(0)
  • 2020-11-22 03:56

    Having searched for the exact same thing and almost implementing a version of this myself, I thought it was worth mentioning that, if you're doing this within a WordPress framework, WP has its own super-handy function for exactly this:

    $myUUID = wp_generate_uuid4();

    You can read the description and the source here.

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