Subversion Repositories oidinfo_api

Rev

Rev 6 | Rev 12 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. <?php
  2.  
  3. /*
  4.  * UUID utils for PHP
  5.  * Copyright 2011-2019 Daniel Marschall, ViaThinkSoft
  6.  * Version 2019-11-04
  7.  *
  8.  * Licensed under the Apache License, Version 2.0 (the "License");
  9.  * you may not use this file except in compliance with the License.
  10.  * You may obtain a copy of the License at
  11.  *
  12.  *     http://www.apache.org/licenses/LICENSE-2.0
  13.  *
  14.  * Unless required by applicable law or agreed to in writing, software
  15.  * distributed under the License is distributed on an "AS IS" BASIS,
  16.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17.  * See the License for the specific language governing permissions and
  18.  * limitations under the License.
  19.  */
  20.  
  21. if (file_exists(__DIR__ . '/mac_utils.inc.phps')) include_once __DIR__ . '/mac_utils.inc.phps';
  22.  
  23. define('UUID_NAMEBASED_NS_DNS',     '6ba7b810-9dad-11d1-80b4-00c04fd430c8');
  24. define('UUID_NAMEBASED_NS_URL',     '6ba7b811-9dad-11d1-80b4-00c04fd430c8');
  25. define('UUID_NAMEBASED_NS_OID',     '6ba7b812-9dad-11d1-80b4-00c04fd430c8');
  26. define('UUID_NAMEBASED_NS_X500_DN', '6ba7b814-9dad-11d1-80b4-00c04fd430c8');
  27.  
  28. function uuid_valid($uuid) {
  29.         $uuid = str_replace(array('-', '{', '}'), '', $uuid);
  30.         $uuid = strtoupper($uuid);
  31.  
  32.         if (strlen($uuid) != 32) return false;
  33.  
  34.         $uuid = preg_replace('@[0-9A-F]@', '', $uuid);
  35.  
  36.         return ($uuid == '');
  37. }
  38.  
  39. # TODO: Don't echo
  40. function uuid_info($uuid) {
  41.         if (!uuid_valid($uuid)) return false;
  42.  
  43.         # $uuid = str_replace(array('-', '{', '}'), '', $uuid);
  44.         $uuid = strtoupper($uuid);
  45.         $uuid = preg_replace('@[^0-9A-F]@', '', $uuid);
  46.  
  47.         $x = hexdec(substr($uuid, 16, 1));
  48.              if ($x >= 14 /* 1110 */) $variant = 3;
  49.         else if ($x >= 12 /* 1100 */) $variant = 2;
  50.         else if ($x >=  8 /* 1000 */) $variant = 1;
  51.         else if ($x >=  0 /* 0000 */) $variant = 0;
  52.  
  53.  
  54.         switch ($variant) {
  55.                 case 0:
  56.                         echo sprintf("%-24s %s\n", "Variant:", "[0xx] NCS (reserved for backward compatibility)");
  57.  
  58.                         /*
  59.                          * Internal structure of variant #0 UUIDs
  60.                          *
  61.                          * The first 6 octets are the number of 4 usec units of time that have
  62.                          * passed since 1/1/80 0000 GMT.  The next 2 octets are reserved for
  63.                          * future use.  The next octet is an address family.  The next 7 octets
  64.                          * are a host ID in the form allowed by the specified address family.
  65.                          *
  66.                          * Note that while the family field (octet 8) was originally conceived
  67.                          * of as being able to hold values in the range [0..255], only [0..13]
  68.                          * were ever used.  Thus, the 2 MSB of this field are always 0 and are
  69.                          * used to distinguish old and current UUID forms.
  70.                          *
  71.                          * +--------------------------------------------------------------+
  72.                          * |                    high 32 bits of time                      |  0-3  .time_high
  73.                          * +-------------------------------+-------------------------------
  74.                          * |     low 16 bits of time       |  4-5               .time_low
  75.                          * +-------+-----------------------+
  76.                          * |         reserved              |  6-7               .reserved
  77.                          * +---------------+---------------+
  78.                          * |    family     |   8                                .family
  79.                          * +---------------+----------...-----+
  80.                          * |            node ID               |  9-16           .node
  81.                          * +--------------------------...-----+
  82.                          *
  83.                          */
  84.  
  85.                         // Example of an UUID: 333a2276-0000-0000-0d00-00809c000000
  86.  
  87.                         # TODO: See https://github.com/cjsv/uuid/blob/master/Doc
  88.  
  89.                         # Timestamp: Count of 4us intervals since 01 Jan 1980 00:00:00 GMT
  90.                         # 1/0,000004 = 250000
  91.                         # Seconds between 1970 and 1980 : 315532800
  92.                         # 250000*315532800=78883200000000
  93.                         $timestamp = substr($uuid, 0, 12);
  94.                         $ts = gmp_init($timestamp, 16);
  95.                         $ts = gmp_add($ts, gmp_init("78883200000000"));
  96.                         $ms = gmp_mod($ts, gmp_init("250000"));
  97.                         $ts = gmp_div($ts, gmp_init("250000"));
  98.                         $ts = gmp_strval($ts);
  99.                         $ms = gmp_strval($ms);
  100.                         $ts = gmdate('Y-m-d H:i:s', $ts)."'".str_pad($ms, 7, '0', STR_PAD_LEFT).' GMT';
  101.                         echo sprintf("%-24s %s\n", "Timestamp:", "[0x$timestamp] $ts");
  102.  
  103.                         $reserved = substr($uuid, 12, 4);
  104.                         echo sprintf("%-24s %s\n", "Reserved:", "0x$reserved");
  105.  
  106.                         # Family 13 (dds) looks like node is 00 | nnnnnn 000000.
  107.                         # Family 2 is presumably (ip).
  108.                         # Not sure if anything else was used.
  109.                         $family_hex = substr($uuid, 16, 2);
  110.                         $family_dec = hexdec($family_hex);
  111.                         if ($family_dec == 2) {
  112.                                 $family_ = 'IP';
  113.                         } else if ($family_dec == 13) {
  114.                                 $family_ = 'DDS (Data Link)';
  115.                         } else {
  116.                                 $family_ = "Unknown ($family_dec)"; # There are probably no more families
  117.                         }
  118.                         echo sprintf("%-24s %s\n", "Family:", "[0x$family_hex = $family_dec] $family_");
  119.  
  120.                         $nodeid = substr($uuid, 18, 14);
  121.                         echo sprintf("%-24s %s\n", "Node ID:", "0x$nodeid");
  122.                         # TODO: interprete node id (the family specifies it)
  123.  
  124.                         break;
  125.                 case 1:
  126.                         echo sprintf("%-24s %s\n", "Variant:", "[10x] RFC 4122 (Leach-Mealling-Salz)");
  127.  
  128.                         $version = hexdec(substr($uuid, 12, 1));
  129.                         switch ($version) {
  130.                                 case 1:
  131.                                         echo sprintf("%-24s %s\n", "Version:", "[1] Time-based with unique random host identifier");
  132.  
  133.                                         # Timestamp: Count of 100ns intervals since 15 Oct 1582 00:00:00
  134.                                         # 1/0,0000001 = 10000000
  135.                                         $timestamp = substr($uuid, 13, 3).substr($uuid, 8, 4).substr($uuid, 0, 8);
  136.                                         $ts = gmp_init($timestamp, 16);
  137.                                         $ts = gmp_sub($ts, gmp_init("122192928000000000"));
  138.                                         $ms = gmp_mod($ts, gmp_init("10000000"));
  139.                                         $ts = gmp_div($ts, gmp_init("10000000"));
  140.                                         $ts = gmp_strval($ts);
  141.                                         $ms = gmp_strval($ms);
  142.                                         $ts = gmdate('Y-m-d H:i:s', $ts)."'".str_pad($ms, 7, '0', STR_PAD_LEFT).' GMT';
  143.                                         echo sprintf("%-24s %s\n", "Timestamp:", "[0x$timestamp] $ts");
  144.  
  145.                                         $x = hexdec(substr($uuid, 16, 4));
  146.                                         $dec = $x & 0x3FFF; // The highest 2 bits are used by "variant" (10x)
  147.                                         $hex = substr($uuid, 16, 4);
  148.                                         echo sprintf("%-24s %s\n", "Clock ID:", "[0x$hex] $dec");
  149.  
  150.                                         $x = substr($uuid, 20, 12);
  151.                                         $nodeid = '';
  152.                                         for ($i=0; $i<6; $i++) {
  153.                                                 $nodeid .= substr($x, $i*2, 2);
  154.                                                 if ($i != 5) $nodeid .= ':';
  155.                                         }
  156.                                         echo sprintf("%-24s %s\n", "Node ID:", "$nodeid");
  157.  
  158.                                         if (function_exists('decode_mac')) {
  159.                                                 echo "\nIn case that this Node ID is a MAC address, here is the interpretation of that MAC address:\n";
  160.                                                 echo decode_mac($nodeid);
  161.                                         }
  162.  
  163.                                         break;
  164.                                 case 2:
  165.                                         echo sprintf("%-24s %s\n", "Version:", "[2] DCE Security version");
  166.  
  167.                                         # The time_low field (which represents an integer in the range [0, 232-1]) is interpreted as a local-ID; that is, an identifier (within the domain specified by clock_seq_low) meaningful to the local host. In the particular case of a POSIX host, when combined with a POSIX UID or POSIX GID domain in the clock_seq_low field (above), the time_low field represents a POSIX UID or POSIX GID, respectively.
  168.                                         $x = substr($uuid, 0, 8);
  169.                                         echo sprintf("%-24s %s\n", "Local ID:", "0x$x");
  170.  
  171.                                         # The clock_seq_low field (which represents an integer in the range [0, 28-1]) is interpreted as a local domain (as represented by sec_rgy_domain_t; see sec_rgy_domain_t ); that is, an identifier domain meaningful to the local host. (Note that the data type sec_rgy_domain_t can potentially hold values outside the range [0, 28-1]; however, the only values currently registered are in the range [0, 2], so this type mismatch is not significant.) In the particular case of a POSIX host, the value sec_rgy_domain_person is to be interpreted as the "POSIX UID domain", and the value sec_rgy_domain_group is to be interpreted as the "POSIX GID domain".
  172.                                         $x = substr($uuid, 18, 2);
  173.                                         if ($x == '00') $domain_info = 'POSIX: User-ID / Non-POSIX: site-defined';
  174.                                         else if ($x == '01') $domain_info = 'POSIX: Group-ID / Non-POSIX: site-defined';
  175.                                         else $domain_info = 'site-defined';
  176.                                         echo sprintf("%-24s %s\n", "Local Domain:", "0x$x ($domain_info)");
  177.  
  178.                                         # Timestamp: Count of 100ns intervals since 15 Oct 1582 00:00:00
  179.                                         # 1/0,0000001 = 10000000
  180.                                         $timestamp = substr($uuid, 13, 3).substr($uuid, 8, 4).'00000000';
  181.                                         $ts = gmp_init($timestamp, 16);
  182.                                         $ts = gmp_sub($ts, gmp_init("122192928000000000"));
  183.                                         $ms = gmp_mod($ts, gmp_init("10000000"));
  184.                                         $ts = gmp_div($ts, gmp_init("10000000"));
  185.                                         $ts = gmp_strval($ts);
  186.                                         $ms = gmp_strval($ms);
  187.                                         $ts_min = gmdate('Y-m-d H:i:s', $ts)."'".str_pad($ms, 7, '0', STR_PAD_LEFT).' GMT';
  188.  
  189.                                         $timestamp = substr($uuid, 13, 3).substr($uuid, 8, 4).'FFFFFFFF';
  190.                                         $ts = gmp_init($timestamp, 16);
  191.                                         $ts = gmp_sub($ts, gmp_init("122192928000000000"));
  192.                                         $ms = gmp_mod($ts, gmp_init("10000000"));
  193.                                         $ts = gmp_div($ts, gmp_init("10000000"));
  194.                                         $ts = gmp_strval($ts);
  195.                                         $ms = gmp_strval($ms);
  196.                                         $ts_max = gmdate('Y-m-d H:i:s', $ts)."'".str_pad($ms, 7, '0', STR_PAD_LEFT).' GMT';
  197.  
  198.                                         $timestamp = substr($uuid, 13, 3).substr($uuid, 8, 4).'xxxxxxxx';
  199.                                         echo sprintf("%-24s %s\n", "Timestamp:", "[0x$timestamp] $ts_min - $ts_max");
  200.  
  201.                                         $x = hexdec(substr($uuid, 16, 2).'00');
  202.                                         $dec_min = $x & 0x3FFF; // The highest 2 bits are used by "variant" (10x)
  203.                                         $x = hexdec(substr($uuid, 16, 2).'FF');
  204.                                         $dec_max = $x & 0x3FFF; // The highest 2 bits are used by "variant" (10x)
  205.                                         $hex = substr($uuid, 16, 2).'xx';
  206.                                         echo sprintf("%-24s %s\n", "Clock ID:", "[0x$hex] $dec_min - $dec_max");
  207.  
  208.                                         $x = substr($uuid, 20, 12);
  209.                                         $nodeid = '';
  210.                                         for ($i=0; $i<6; $i++) {
  211.                                                 $nodeid .= substr($x, $i*2, 2);
  212.                                                 if ($i != 5) $nodeid .= ':';
  213.                                         }
  214.                                         echo sprintf("%-24s %s\n", "Node ID:", "$nodeid");
  215.  
  216.                                         if (function_exists('decode_mac')) {
  217.                                                 echo "\nIn case that this Node ID is a MAC address, here is the interpretation of that MAC address:\n";
  218.                                                 echo decode_mac($nodeid);
  219.                                         }
  220.  
  221.                                         break;
  222.                                 case 3:
  223.                                         echo sprintf("%-24s %s\n", "Version:", "[3] Name-based (MD5 hash)");
  224.  
  225.                                         $hash = str_replace('-', '', strtolower($uuid));
  226.                                         $hash[12] = '?'; // was overwritten by version
  227.                                         $hash[16] = '?'; // was partially overwritten by variant
  228.  
  229.                                         echo sprintf("%-24s %s\n", "MD5(Namespace+Subject):", "$hash");
  230.  
  231.                                         break;
  232.                                 case 4:
  233.                                         echo sprintf("%-24s %s\n", "Version:", "[4] Random");
  234.  
  235.                                         $rand = '';
  236.                                         for ($i=0; $i<16; $i++) {
  237.                                                 $bin = base_convert(substr($uuid, $i*2, 2), 16, 2);
  238.                                                 $bin = str_pad($bin, 8, "0", STR_PAD_LEFT);
  239.  
  240.                                                 if ($i == 6) {
  241.                                                         $bin[0] = 'x';
  242.                                                         $bin[1] = 'x';
  243.                                                 } else if ($i == 8) {
  244.                                                         $bin[0] = 'x';
  245.                                                         $bin[1] = 'x';
  246.                                                         $bin[2] = 'x';
  247.                                                         $bin[3] = 'x';
  248.                                                 }
  249.  
  250.                                                 $rand .= "$bin ";
  251.                                         }
  252.  
  253.                                         echo sprintf("%-24s %s\n", "Random bits:", trim($rand));
  254.  
  255.                                         break;
  256.                                 case 5:
  257.                                         echo sprintf("%-24s %s\n", "Version:", "[5] Name-based (SHA-1 hash)");
  258.  
  259.                                         $hash = str_replace('-', '', strtolower($uuid));
  260.                                         $hash[12] = '?'; // was overwritten by version
  261.                                         $hash[16] = '?'; // was partially overwritten by variant
  262.                                         $hash .= '????????'; // was cut off
  263.  
  264.                                         echo sprintf("%-24s %s\n", "SHA1(Namespace+Subject):", "$hash");
  265.  
  266.  
  267.                                         break;
  268.                                 default:
  269.                                         echo sprintf("%-24s %s\n", "Version:", "[$version] Unknown");
  270.                                         break;
  271.                         }
  272.  
  273.                         break;
  274.                 case 2:
  275.                         echo sprintf("%-24s %s\n", "Variant:", "[110] Reserved for Microsoft Corporation");
  276.                         break;
  277.                 case 3:
  278.                         echo sprintf("%-24s %s\n", "Variant:", "[111] Reserved for future use");
  279.                         break;
  280.         }
  281. }
  282.  
  283. function uuid_canonize($uuid) {
  284.         if (!uuid_valid($uuid)) return false;
  285.         return oid_to_uuid(uuid_to_oid($uuid));
  286. }
  287.  
  288. function oid_to_uuid($oid) {
  289.         if (!is_uuid_oid($oid)) return false;
  290.  
  291.         if ($oid[0] == '.') {
  292.                 $oid = substr($oid, 1);
  293.         }
  294.         $ary = explode('.', $oid);
  295.         $val = $ary[2];
  296.  
  297.         $x = gmp_init($val, 10);
  298.         $y = gmp_strval($x, 16);
  299.         $y = str_pad($y, 32, "0", STR_PAD_LEFT);
  300.         return substr($y,  0, 8).'-'.
  301.                substr($y,  8, 4).'-'.
  302.                substr($y, 12, 4).'-'.
  303.                substr($y, 16, 4).'-'.
  304.                substr($y, 20, 12);
  305. }
  306.  
  307. function is_uuid_oid($oid, $only_allow_root=false) {
  308.         if ($oid[0] == '.') $oid = substr($oid, 1); // remove leading dot
  309.  
  310.         $ary = explode('.', $oid);
  311.  
  312.         if ($only_allow_root) {
  313.                 if (count($ary) != 3) return false;
  314.         }
  315.  
  316.         if ($ary[0] != '2') return false;
  317.         if ($ary[1] != '25') return false;
  318.         for ($i=2; $i<count($ary); $i++) {
  319.                 $v = $ary[$i];
  320.                 if (!is_numeric($v)) return false;
  321.                 if ($i == 2) {
  322.                         // Must be in the range of 128 bit UUID
  323.                         $test = gmp_init($v, 10);
  324.                         if (strlen(gmp_strval($test, 16)) > 32) return false;
  325.                 }
  326.                 if ($v < 0) return false;
  327.         }
  328.  
  329.         return true;
  330. }
  331.  
  332. function uuid_to_oid($uuid) {
  333.         if (!uuid_valid($uuid)) return false;
  334.  
  335.         $uuid = str_replace(array('-', '{', '}'), '', $uuid);
  336.         $x = gmp_init($uuid, 16);
  337.         return '2.25.'.gmp_strval($x, 10); # TODO: parameter with or without leading dot
  338. }
  339.  
  340. function gen_uuid($prefer_timebased = true) {
  341.         if ($prefer_timebased) $uuid = gen_uuid_timebased();
  342.         if ($uuid === false) $uuid = gen_uuid_random();
  343.         return $uuid;
  344. }
  345.  
  346. // Version 1 (Time based) UUID
  347. function gen_uuid_timebased() {
  348.         # On Debian: aptitude install php-uuid
  349.         # extension_loaded('uuid')
  350.         if (function_exists('uuid_create')) {
  351.                 # OSSP uuid extension like seen in php5-uuid at Debian 8
  352.                 /*
  353.                 $x = uuid_create($context);
  354.                 uuid_make($context, UUID_MAKE_V1);
  355.                 uuid_export($context, UUID_FMT_STR, $uuid);
  356.                 return trim($uuid);
  357.                 */
  358.  
  359.                 # PECL uuid extension like seen in php-uuid at Debian 9
  360.                 return trim(uuid_create(UUID_TYPE_TIME));
  361.         }
  362.  
  363.         # On Debian: aptitude install uuid-runtime
  364.         $out = array();
  365.         exec('uuidgen -t', $out, $ec);
  366.         if ($ec == 0) return $out[0];
  367.  
  368.         # TODO: Implement the time based generation routine ourselves!
  369.         # At the moment we cannot determine the time based UUID
  370.         return false;
  371. }
  372.  
  373. // Version 2 (DCE Security) UUID
  374. function gen_uuid_dce($domain, $id) {
  375.         # Start with a version 1 UUID
  376.         $uuid = gen_uuid_timebased();
  377.  
  378.         # Add ID
  379.         $uuid = str_pad(dechex($id), 8, '0', STR_PAD_LEFT) . substr($uuid, 8);
  380.  
  381.         # Add domain
  382.         $uuid = substr($uuid,0,21) . str_pad(dechex($domain), 2, '0', STR_PAD_LEFT) . substr($uuid, 23);
  383.  
  384.         # Change version to 2
  385.         $uuid[14] = '2';
  386.  
  387.         return $uuid;
  388. }
  389.  
  390. // Version 3 (MD5 name based) UUID
  391. function gen_uuid_md5_namebased($namespace_uuid, $name) {
  392.         if (!uuid_valid($namespace_uuid)) return false;
  393.         $namespace_uuid = uuid_canonize($namespace_uuid);
  394.         $namespace_uuid = str_replace('-', '', $namespace_uuid);
  395.         $namespace_uuid = hex2bin($namespace_uuid);
  396.  
  397.         $hash = md5($namespace_uuid.$name);
  398.         $hash[12] = '3'; // Set version: 3 = MD5
  399.         $hash[16] = dechex(hexdec($hash[16]) & 0x3 | 0x8); // Set variant to "10xx" (RFC4122)
  400.  
  401.         return substr($hash,  0, 8).'-'.
  402.                substr($hash,  8, 4).'-'.
  403.                substr($hash, 12, 4).'-'.
  404.                substr($hash, 16, 4).'-'.
  405.                substr($hash, 20, 12);
  406. }
  407.  
  408. // Version 4 (Random) UUID
  409. function gen_uuid_random() {
  410.         # On Debian: aptitude install php-uuid
  411.         # extension_loaded('uuid')
  412.         if (function_exists('uuid_create')) {
  413.                 # OSSP uuid extension like seen in php5-uuid at Debian 8
  414.                 /*
  415.                 $x = uuid_create($context);
  416.                 uuid_make($context, UUID_MAKE_V4);
  417.                 uuid_export($context, UUID_FMT_STR, $uuid);
  418.                 return trim($uuid);
  419.                 */
  420.  
  421.                 # PECL uuid extension like seen in php-uuid at Debian 9
  422.                 return trim(uuid_create(UUID_TYPE_RANDOM));
  423.         }
  424.  
  425.         # On Debian: aptitude install uuid-runtime
  426.         $out = array();
  427.         exec('uuidgen -r', $out, $ec);
  428.         if ($ec == 0) return $out[0];
  429.  
  430.         # On Debian Jessie: UUID V4 (Random)
  431.         if (file_exists('/proc/sys/kernel/random/uuid')) {
  432.                 return file_get_contents('/proc/sys/kernel/random/uuid');
  433.         }
  434.  
  435.         # Make the UUID by ourselves
  436.         # Source: http://rogerstringer.com/2013/11/15/generate-uuids-php
  437.         return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
  438.                 mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
  439.                 mt_rand( 0, 0xffff ),
  440.                 mt_rand( 0, 0x0fff ) | 0x4000,
  441.                 mt_rand( 0, 0x3fff ) | 0x8000,
  442.                 mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff )
  443.         );
  444. }
  445.  
  446. // Version 5 (SHA1 name based) UUID
  447. function gen_uuid_sha1_namebased($namespace_uuid, $name) {
  448.         $namespace_uuid = str_replace('-', '', $namespace_uuid);
  449.         $namespace_uuid = hex2bin($namespace_uuid);
  450.  
  451.         $hash = sha1($namespace_uuid.$name);
  452.         $hash[12] = '5'; // Set version: 5 = SHA1
  453.         $hash[16] = dechex(hexdec($hash[16]) & 0x3 | 0x8); // Set variant to "10xx" (RFC4122)
  454.  
  455.         return substr($hash,  0, 8).'-'.
  456.                substr($hash,  8, 4).'-'.
  457.                substr($hash, 12, 4).'-'.
  458.                substr($hash, 16, 4).'-'.
  459.                substr($hash, 20, 12);
  460. }
  461.  
  462. function uuid_numeric_value($uuid) {
  463.         $oid = uuid_to_oid($uuid);
  464.         if (!$oid) return false;
  465.         return substr($oid, strlen('2.25.'));
  466. }
  467.  
  468. function uuid_c_syntax($uuid) {
  469.         $uuid = str_replace('{', '', $uuid);
  470.         return '{ 0x' . substr($uuid, 0, 8) .
  471.                 ', 0x' . substr($uuid, 9, 4) .
  472.                 ', 0x' . substr($uuid, 14, 4) .
  473.                 ', { 0x' . substr($uuid, 19, 2).
  474.                 ', 0x' . substr($uuid, 21, 2) .
  475.                 ', 0x' . substr($uuid, 24, 2) .
  476.                 ', 0x' . substr($uuid, 26, 2) .
  477.                 ', 0x' . substr($uuid, 28, 2) .
  478.                 ', 0x' . substr($uuid, 30, 2) .
  479.                 ', 0x' . substr($uuid, 32, 2) .
  480.                 ', 0x' . substr($uuid, 34, 2) . ' } }';
  481. }
  482.  
  483. # ---
  484.  
  485. // http://php.net/manual/de/function.hex2bin.php#113057
  486. if ( !function_exists( 'hex2bin' ) ) {
  487.     function hex2bin( $str ) {
  488.         $sbin = "";
  489.         $len = strlen( $str );
  490.         for ( $i = 0; $i < $len; $i += 2 ) {
  491.             $sbin .= pack( "H*", substr( $str, $i, 2 ) );
  492.         }
  493.  
  494.         return $sbin;
  495.     }
  496. }
  497.