3v4l.org

run code in 300+ PHP versions simultaneously
<?php class Uuid { const MD5 = 3; const SHA1 = 5; /** * 00001111 Clears all bits of version byte with AND * @var int */ const CLEAR_VER = 15; /** * 00111111 Clears all relevant bits of variant byte with AND * @var int */ const CLEAR_VAR = 63; /** * 11100000 Variant reserved for future use * @var int */ const VAR_RES = 224; /** * 11000000 Microsoft UUID variant * @var int */ const VAR_MS = 192; /** * 10000000 The RFC 4122 variant (this variant) * @var int */ const VAR_RFC = 128; /** * 00000000 The NCS compatibility variant * @var int */ const VAR_NCS = 0; /** * 00010000 * @var int */ const VERSION_1 = 16; /** * 00110000 * @var int */ const VERSION_3 = 48; /** * 01000000 * @var int */ const VERSION_4 = 64; /** * 01010000 * @var int */ const VERSION_5 = 80; /** * Time (in 100ns steps) between the start of the UTC and Unix epochs * @var int */ const INTERVAL = 0x01b21dd213814000; /** * @var string */ const NS_DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; /** * @var string */ const NS_URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; /** * @var string */ const NS_OID = '6ba7b812-9dad-11d1-80b4-00c04fd430c8'; /** * @var string */ const NS_X500 = '6ba7b814-9dad-11d1-80b4-00c04fd430c8'; /** * @var string */ protected static $randomFunc = 'randomMcrypt'; protected $bytes; protected $hex; protected $string; protected $urn; protected $version; protected $variant; protected $node; protected $time; /** * @param string $uuid * @throws Exception */ protected function __construct($uuid) { if (!empty($uuid) && strlen($uuid) !== 16) { throw new Exception('Input must be a 128-bit integer.'); } $this->bytes = $uuid; // Optimize the most common use $this->string = bin2hex(substr($uuid, 0, 4)) . "-" . bin2hex(substr($uuid, 4, 2)) . "-" . bin2hex(substr($uuid, 6, 2)) . "-" . bin2hex(substr($uuid, 8, 2)) . "-" . bin2hex(substr($uuid, 10, 6)); } /** * @param int $ver * @param string $node * @param string $ns * @return Uuid * @throws Exception */ public static function generate($ver = 1, $node = null, $ns = null) { /* Create a new UUID based on provided data. */ switch ((int)$ver) { case 1: return new static(static::mintTime($node)); case 2: // Version 2 is not supported throw new \Exception('Version 2 is unsupported.'); case 3: return new static(static::mintName(static::MD5, $node, $ns)); case 4: return new static(static::mintRand()); case 5: return new static(static::mintName(static::SHA1, $node, $ns)); default: throw new \Exception('Selected version is invalid or unsupported.'); } } /** * Generates a Version 1 UUID. * These are derived from the time at which they were generated. * * @param string $node * @return string */ protected static function mintTime($node = null) { /** Get time since Gregorian calendar reform in 100ns intervals * This is exceedingly difficult because of PHP's (and pack()'s) * integer size limits. * Note that this will never be more accurate than to the microsecond. */ $time = microtime(1) * 10000000 + static::INTERVAL; // Convert to a string representation $time = sprintf("%F", $time); //strip decimal point preg_match("/^\d+/", $time, $time); // And now to a 64-bit binary representation $time = base_convert($time[0], 10, 16); $time = pack("H*", str_pad($time, 16, "0", STR_PAD_LEFT)); // Reorder bytes to their proper locations in the UUID // $uuid = $time[4] . $time[5] . $time[6] . $time[7] . $time[2] . $time[3] . $time[0] . $time[1]; $uuid = $time[0] . $time[1] . $time[2] . $time[3] . $time[4] . $time[5] . $time[6] . $time[7]; // Generate a random clock sequence $uuid .= static::randomBytes(2); // set variant $uuid[8] = chr(ord($uuid[8]) & static::CLEAR_VAR | static::VAR_RFC); // set version $uuid[6] = chr(ord($uuid[6]) & static::CLEAR_VER | static::VERSION_1); // Set the final 'node' parameter, a MAC address /* if (!is_null($node)) { $node = static::makeBin($node, 6); } //If no node was provided or if the node was invalid, generate a random MAC address and set the multicast bit if (is_null($node)) { $node = static::randomBytes(6); $node[0] = pack("C", ord($node[0]) | 1); } $uuid .= $node; */ return bindec($uuid); } /** * Randomness is returned as a string of bytes * * @param $bytes * @return string */ public static function randomBytes($bytes) { return call_user_func(array('static', static::initRandom()), $bytes); } /** * Trying for openSSL and Mcrypt random generators. Fallback to mt_rand * Since laravel 4.* and 5.0 requires Mcrypt and 5.1 requires OpenSSL the fallback should never be used. * * @throws Exception * @return string */ public static function initRandom() { if (function_exists('openssl_random_pseudo_bytes')) { return 'randomOpenSSL'; } elseif (function_exists('mcrypt_encrypt')) { return 'randomMcrypt'; } // This is not the best randomizer (using mt_rand)... return 'randomTwister'; } /** * Insure that an input string is either binary or hexadecimal. * Returns binary representation, or false on failure. * * @param string $str * @param integer $len * @return string|null */ protected static function makeBin($str, $len) { if ($str instanceof self) { return $str->bytes; } if (strlen($str) === $len) { return $str; } else { // strip URN scheme and namespace $str = preg_replace('/^urn:uuid:/is', '', $str); } // strip non-hex characters $str = preg_replace('/[^a-f0-9]/is', '', $str); if (strlen($str) !== ($len * 2)) { return null; } else { return pack("H*", $str); } } /** * Generates a Version 3 or Version 5 UUID. * These are derived from a hash of a name and its namespace, in binary form. * * @param string $ver * @param string $node * @param string $ns * @return string * @throws Exception */ protected static function mintName($ver, $node, $ns) { if (empty($node)) { throw new Exception('A name-string is required for Version 3 or 5 UUIDs.'); } // if the namespace UUID isn't binary, make it so $ns = static::makeBin($ns, 16); if (is_null($ns)) { throw new Exception('A binary namespace is required for Version 3 or 5 UUIDs.'); } $version = null; $uuid = null; switch ($ver) { case static::MD5: $version = static::VERSION_3; $uuid = md5($ns . $node, 1); break; case static::SHA1: $version = static::VERSION_5; $uuid = substr(sha1($ns . $node, 1), 0, 16); break; default: // no default really required here } // set variant $uuid[8] = chr(ord($uuid[8]) & static::CLEAR_VAR | static::VAR_RFC); // set version $uuid[6] = chr(ord($uuid[6]) & static::CLEAR_VER | $version); return ($uuid); } /** * Generate a Version 4 UUID. * These are derived solely from random numbers. * generate random fields * * @return string */ protected static function mintRand() { $uuid = static::randomBytes(16); // set variant $uuid[8] = chr(ord($uuid[8]) & static::CLEAR_VAR | static::VAR_RFC); // set version $uuid[6] = chr(ord($uuid[6]) & static::CLEAR_VER | static::VERSION_4); return $uuid; } /** * Import an existing UUID * * @param string $uuid * @return Uuid */ public static function import($uuid) { return new static(static::makeBin($uuid, 16)); } /** * Compares the binary representations of two UUIDs. * The comparison will return true if they are bit-exact, * or if neither is valid. * * @param string $a * @param string $b * @return string|string */ public static function compare($a, $b) { if (static::makeBin($a, 16) == static::makeBin($b, 16)) { return true; } else { return false; } } /** * Get the specified number of random bytes, using openssl_random_pseudo_bytes(). * Randomness is returned as a string of bytes. * * @param $bytes * @return mixed */ protected static function randomOpenSSL($bytes) { return openssl_random_pseudo_bytes($bytes); } /** * Get the specified number of random bytes, using mcrypt_create_iv(). * Randomness is returned as a string of bytes. * * @param $bytes * @return string */ protected static function randomMcrypt($bytes) { return mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM); } /** * Get the specified number of random bytes, using mt_rand(). * Randomness is returned as a string of bytes. * * @param integer $bytes * @return string */ protected static function randomTwister($bytes) { $rand = ""; for ($a = 0; $a < $bytes; $a++) { $rand .= chr(mt_rand(0, 255)); } return $rand; } /** * @param string $var * @return string|string|number|number|number|number|number|NULL|number|NULL|NULL */ public function __get($var) { switch ($var) { case "bytes": return $this->bytes; // no break case "hex": return bin2hex($this->bytes); // no break case "string": return $this->__toString(); // no break case "urn": return "urn:uuid:" . $this->__toString(); // no break case "version": return ord($this->bytes[6]) >> 4; // no break case "variant": $byte = ord($this->bytes[8]); if ($byte >= static::VAR_RES) { return 3; } elseif ($byte >= static::VAR_MS) { return 2; } elseif ($byte >= static::VAR_RFC) { return 1; } else { return 0; } // no break case "node": if (ord($this->bytes[6]) >> 4 == 1) { return bin2hex(substr($this->bytes, 10)); } else { return null; } // no break case "time": if (ord($this->bytes[6]) >> 4 == 1) { // Restore contiguous big-endian byte order $time = bin2hex($this->bytes[6] . $this->bytes[7] . $this->bytes[4] . $this->bytes[5] . $this->bytes[0] . $this->bytes[1] . $this->bytes[2] . $this->bytes[3]); // Clear version flag $time[0] = "0"; // Do some reverse arithmetic to get a Unix timestamp return (hexdec($time) - static::INTERVAL) / 10000000; } else { return null; } // no break default: return null; // no break } } /** * Return the UUID * * @return string */ public function __toString() { return $this->string; } } $uuid = Uuid::generate(); echo($uuid);

Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).

VersionSystem time (s)User time (s)Memory (MiB)
7.3.120.0070.01015.28
7.3.110.0130.00314.99
7.3.100.0060.00915.11
7.3.90.0090.00615.24
7.3.80.0060.00615.02
7.3.70.0090.00615.21
7.3.60.0040.01215.20
7.3.50.0000.01415.11
7.3.40.0070.00714.99
7.3.30.0060.00915.13
7.3.20.0060.00916.60
7.3.10.0000.01117.04
7.3.00.0090.00317.02
7.2.240.0080.00315.43
7.2.230.0100.00715.52
7.2.220.0030.00915.58
7.2.210.0140.00315.23
7.2.200.0030.01415.37
7.2.190.0030.01415.52
7.2.180.0100.00715.46
7.2.170.0110.00415.46
7.2.160.0060.00915.48
7.2.150.0120.00317.09
7.2.140.0060.00917.19
7.2.130.0000.01417.04
7.2.120.0000.01216.90
7.2.110.0140.00417.19
7.2.100.0070.01117.11
7.2.90.0060.00917.16
7.2.80.0110.00716.98
7.2.70.0000.01217.21
7.2.60.0070.00417.35
7.2.50.0060.01116.97
7.2.40.0070.00717.05
7.2.30.0080.00317.25
7.2.20.0060.00916.90
7.2.10.0030.01317.31
7.2.00.0070.00918.56
7.1.330.0080.00615.81
7.1.320.0120.00315.96
7.1.310.0040.01116.16
7.1.300.0000.01415.73
7.1.290.0080.00816.03
7.1.280.0030.01016.02
7.1.270.0070.00415.98
7.1.260.0100.00615.91
7.1.250.0040.01116.21
7.1.100.0060.00918.21
7.1.70.0040.00417.61
7.1.60.0110.01419.17
7.1.50.0000.02117.30
7.1.00.0000.08022.30
7.0.200.0000.01016.94
7.0.100.0070.04320.09
7.0.90.0100.05320.08
7.0.80.0100.06020.10
7.0.70.0130.03720.00
7.0.60.0070.04720.08
7.0.50.0100.04320.44
7.0.40.0000.04020.13
7.0.30.0070.08320.10
7.0.20.0070.08720.20
7.0.10.0100.07720.09
7.0.00.0100.06320.08
5.6.280.0030.06321.10
5.6.250.0030.04320.74
5.6.240.0000.04320.82
5.6.230.0030.04320.69
5.6.220.0030.04020.63
5.6.210.0000.04320.59
5.6.200.0000.04321.20
5.6.190.0030.04321.05
5.6.180.0070.07321.13
5.6.170.0030.08721.28
5.6.160.0070.05321.13
5.6.150.0100.08321.08
5.6.140.0330.05721.20
5.6.130.0100.07320.99
5.6.120.0100.08021.21
5.6.110.0030.08321.23
5.6.100.0070.08321.12
5.6.90.0070.08321.26
5.6.80.0130.06020.52
5.6.70.0200.06720.48
5.6.60.0100.07020.56
5.6.50.0100.07320.43
5.6.40.0130.07320.53
5.6.30.0030.05320.48
5.6.20.0200.05320.39
5.6.10.0070.08720.55
5.6.00.0130.06720.41
5.5.380.0000.06020.66
5.5.370.0000.04320.53
5.5.360.0030.03720.63
5.5.350.0070.03720.54
5.5.340.0000.04720.99
5.5.330.0070.08020.89
5.5.320.0070.08020.96
5.5.310.0170.07320.87
5.5.300.0070.08020.93
5.5.290.0130.07320.99
5.5.280.0100.08320.84
5.5.270.0030.08321.00
5.5.260.0070.08720.92
5.5.250.0170.04020.80
5.5.240.0170.06720.26
5.5.230.0130.07020.22
5.5.220.0030.06020.36
5.5.210.0170.07020.36
5.5.200.0170.06020.39
5.5.190.0070.06320.19
5.5.180.0070.08020.35
5.5.160.0030.08020.23
5.5.150.0030.07720.29
5.5.140.0070.08020.27
5.5.130.0030.04320.05
5.5.120.0130.06720.22
5.5.110.0070.08020.28
5.5.100.0070.08320.18
5.5.90.0030.08020.23
5.5.80.0100.05020.26
5.5.70.0130.07020.13
5.5.60.0070.05720.07
5.5.50.0170.04020.20
5.5.40.0100.07720.18
5.5.30.0070.07020.20
5.5.20.0100.07720.19
5.5.10.0070.08020.08
5.5.00.0100.06720.08
5.4.450.0000.09319.23
5.4.440.0100.08319.55
5.4.430.0070.08019.59
5.4.420.0130.07319.38
5.4.410.0100.07319.29
5.4.400.0070.08018.94
5.4.390.0030.06019.10
5.4.380.0130.07319.22
5.4.370.0030.08718.95
5.4.360.0100.07319.14
5.4.350.0200.06018.91
5.4.340.0030.08319.16
5.4.320.0030.08018.96
5.4.310.0100.07319.25
5.4.300.0030.08019.20
5.4.290.0030.06019.14
5.4.280.0070.08319.04
5.4.270.0030.08319.09
5.4.260.0130.07019.13
5.4.250.0070.08319.21
5.4.240.0170.05319.04
5.4.230.0030.08318.93
5.4.220.0000.08019.27
5.4.210.0200.05319.24
5.4.200.0070.07319.26
5.4.190.0130.07018.91
5.4.180.0000.07719.13
5.4.170.0130.06318.95
5.4.160.0070.07318.83
5.4.150.0030.08319.13
5.4.140.0070.06716.48
5.4.130.0300.05316.45
5.4.120.0130.06716.50
5.4.110.0100.07016.60
5.4.100.0000.06316.55
5.4.90.0130.04316.50
5.4.80.0100.06016.40
5.4.70.0100.07016.48
5.4.60.0130.06716.45
5.4.50.0100.06716.39
5.4.40.0100.07016.50
5.4.30.0070.07716.37
5.4.20.0070.05716.36
5.4.10.0070.07316.41
5.4.00.0030.07715.70

preferences:
38.44 ms | 401 KiB | 5 Q