PHP函数生成v4 UUID

所以我一直在做一些挖掘工作,我一直在拼凑一个可以在PHP中生成有效v4 UUID的函数。 这是我能够最接近的。 我在十六进制,十进制,二进制,PHP的按位运算符等方面的知识几乎不存在。 该功能可以生成有效的v4 UUID,直到一个区域。 v4 UUID应该采用以下形式:

xxxxxxxx-xxxx- 4 xxx- y xxx-xxxxxxxxxxxx

其中y是8,9,A或B.这是函数失败的地方,因为它不遵守这个规则。

我希望在这方面有比我更多知识的人可以借我一把,帮助我解决这个问题,所以它坚持这个规则。

功能如下:

<?php

function gen_uuid() {
 $uuid = array(
  'time_low'  => 0,
  'time_mid'  => 0,
  'time_hi'  => 0,
  'clock_seq_hi' => 0,
  'clock_seq_low' => 0,
  'node'   => array()
 );

 $uuid['time_low'] = mt_rand(0, 0xffff) + (mt_rand(0, 0xffff) << 16);
 $uuid['time_mid'] = mt_rand(0, 0xffff);
 $uuid['time_hi'] = (4 << 12) | (mt_rand(0, 0x1000));
 $uuid['clock_seq_hi'] = (1 << 7) | (mt_rand(0, 128));
 $uuid['clock_seq_low'] = mt_rand(0, 255);

 for ($i = 0; $i < 6; $i++) {
  $uuid['node'][$i] = mt_rand(0, 255);
 }

 $uuid = sprintf('%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x',
  $uuid['time_low'],
  $uuid['time_mid'],
  $uuid['time_hi'],
  $uuid['clock_seq_hi'],
  $uuid['clock_seq_low'],
  $uuid['node'][0],
  $uuid['node'][1],
  $uuid['node'][2],
  $uuid['node'][3],
  $uuid['node'][4],
  $uuid['node'][5]
 );

 return $uuid;
}

?>

感谢任何能够帮助我的人。


从这个PHP手册的评论中,你可以使用这个:

function gen_uuid() {
    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 )
    );
}

不要将其分解为单独的字段,而是更容易生成随机数据块并更改单个字节位置。 您还应该使用比mt_rand()更好的随机数生成器。

根据RFC 4122 - 第4.4节,您需要更改这些字段:

  • time_hi_and_version (第7个八位字节的第4-7位),
  • clock_seq_hi_and_reserved (第9个八位字节的第6和7位)
  • 所有其他的122位应该是足够随机的。

    以下方法产生利用随机数据的128位openssl_random_pseudo_bytes()使得在八位位组排列,然后使用bin2hex()vsprintf()做最后的格式。

    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));
    

    使用PHP 7,使用random_bytes()生成随机字节序列更加简单:

    echo guidv4(random_bytes(16));
    

    任何人使用作曲家依赖关系,你可能想考虑这个库:https://github.com/ramsey/uuid

    它没有比这更容易:

    Uuid::uuid4();
    
    链接地址: http://www.djcxy.com/p/16253.html

    上一篇: PHP function to generate v4 UUID

    下一篇: numeric string in JavaScript?