복붙노트

v4 UUID를 생성하는 PHP 함수

PHP

v4 UUID를 생성하는 PHP 함수

그래서 저는 주위를 파고 들며 PHP에서 유효한 v4 UUID를 생성하는 함수를 조합하려고했습니다. 이것은 내가 올 수 있었던 가장 가까운 곳이다. 16 진수, 10 진수, 2 진수, PHP의 비트 연산자 등의 지식은 거의 존재하지 않습니다. 이 함수는 하나의 영역까지 유효한 v4 UUID를 생성합니다. v4 UUID는 다음 형식이어야합니다.

여기서 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;
}

?>

나를 도울 수있는 사람 덕분에.

해결법

  1. ==============================

    1.PHP 매뉴얼에서이 주석을 사용하면 다음과 같이 사용할 수 있습니다 :

    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 )
        );
    }
    
  2. ==============================

    2.개별 필드로 나누는 대신 데이터의 무작위 블록을 생성하고 개별 바이트 위치를 변경하는 것이 더 쉽습니다. 또한 mt_rand ()보다 더 나은 난수 생성기를 사용해야합니다.

    개별 필드로 나누는 대신 데이터의 무작위 블록을 생성하고 개별 바이트 위치를 변경하는 것이 더 쉽습니다. 또한 mt_rand ()보다 더 나은 난수 생성기를 사용해야합니다.

    RFC 4122 - 섹션 4.4에 따라 다음 필드를 변경해야합니다.

    나머지 122 비트는 모두 충분히 랜덤해야합니다.

    다음 접근 방식은 openssl_random_pseudo_bytes ()를 사용하여 128 비트의 무작위 데이터를 생성하고, 옥텟에 대한 순열을 작성한 다음 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));
    
  3. ==============================

    3.작곡가 의존성을 사용하는 사람이라면 누구나이 라이브러리를 고려해 볼 수 있습니다. https://github.com/ramsey/uuid

    작곡가 의존성을 사용하는 사람이라면 누구나이 라이브러리를 고려해 볼 수 있습니다. https://github.com/ramsey/uuid

    이것보다 더 쉽지는 않습니다 :

    Uuid::uuid4();
    
  4. ==============================

    4.유닉스 시스템에서는 시스템 커널을 사용하여 uuid를 생성합니다.

    유닉스 시스템에서는 시스템 커널을 사용하여 uuid를 생성합니다.

    file_get_contents('/proc/sys/kernel/random/uuid')
    

    Credit Samveen (https://serverfault.com/a/529319/210994)

  5. ==============================

    5.v4 uuid를 찾기 위해 필자는이 페이지를 처음 방문한 다음 http://php.net/manual/en/function.com-create-guid.php에서이 파일을 찾았습니다.

    v4 uuid를 찾기 위해 필자는이 페이지를 처음 방문한 다음 http://php.net/manual/en/function.com-create-guid.php에서이 파일을 찾았습니다.

    function guidv4()
    {
        if (function_exists('com_create_guid') === true)
            return trim(com_create_guid(), '{}');
    
        $data = openssl_random_pseudo_bytes(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));
    }
    

    신용 : pavel.volyntsev

    편집 : 명확히하기 위해이 함수는 항상 v4 uuid (PHP> = 5.3.0)를 제공합니다.

    com_create_guid 함수를 사용할 수있을 때 (일반적으로 Windows에서만 사용 가능),이를 사용하여 중괄호를 제거합니다.

    존재하지 않으면 (Linux),이 강력한 임의의 openssl_random_pseudo_bytes 함수로 돌아가고 vsprintf를 사용하여 v4uuid로 포맷합니다.

  6. ==============================

    6.내 대답은 주석 uniqid 사용자 의견을 기반으로하지만 openssl_random_pseudo_bytes 함수를 사용하여 임의의 문자열을 생성하는 대신 / dev / urandom에서 읽습니다.

    내 대답은 주석 uniqid 사용자 의견을 기반으로하지만 openssl_random_pseudo_bytes 함수를 사용하여 임의의 문자열을 생성하는 대신 / 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
    
  7. ==============================

    7.브로 파의 대답에서 영감을 얻었습니다.

    브로 파의 대답에서 영감을 얻었습니다.

    preg_replace_callback('/[xy]/', function ($matches)
    {
      return dechex('x' == $matches[0] ? mt_rand(0, 15) : (mt_rand(0, 15) & 0x3 | 0x8));
    }
    , 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx');
    

    또는 익명의 기능을 사용할 수없는 경우

    preg_replace_callback('/[xy]/', create_function(
      '$matches',
      'return dechex("x" == $matches[0] ? mt_rand(0, 15) : (mt_rand(0, 15) & 0x3 | 0x8));'
    )
    , 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx');
    
  8. ==============================

    8.CakePHP를 사용한다면 그들의 메소드 CakeText :: uuid ()를 사용할 수 있습니다; CakeText 클래스에서 RFC4122Uuid를 생성합니다.

    CakePHP를 사용한다면 그들의 메소드 CakeText :: uuid ()를 사용할 수 있습니다; CakeText 클래스에서 RFC4122Uuid를 생성합니다.

  9. ==============================

    9.tom, http://www.php.net/manual/en/function.uniqid.php에서

    tom, http://www.php.net/manual/en/function.uniqid.php에서

    $r = unpack('v*', fread(fopen('/dev/random', 'r'),16));
    $uuid = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
        $r[1], $r[2], $r[3], $r[4] & 0x0fff | 0x4000,
        $r[5] & 0x3fff | 0x8000, $r[6], $r[7], $r[8])
    
  10. ==============================

    10.mysql을 사용하여 uuid를 생성하는 것은 어떻습니까?

    mysql을 사용하여 uuid를 생성하는 것은 어떻습니까?

    $conn = new mysqli($servername, $username, $password, $dbname, $port);
    
    $query = 'SELECT UUID()';
    echo $conn->query($query)->fetch_row()[0];
    
  11. from https://stackoverflow.com/questions/2040240/php-function-to-generate-v4-uuid by cc-by-sa and MIT license