1: | <?php |
2: | /* |
3: | You may not change or alter any portion of this comment or credits |
4: | of supporting developers from this source code or any supporting source code |
5: | which is considered copyrighted (c) material of the original comment or credit authors. |
6: | |
7: | This program is distributed in the hope that it will be useful, |
8: | but WITHOUT ANY WARRANTY; without even the implied warranty of |
9: | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
10: | */ |
11: | |
12: | namespace Xmf; |
13: | |
14: | /** |
15: | * Generate UUID |
16: | * |
17: | * @category Xmf\Uuid |
18: | * @package Xmf |
19: | * @author Richard Griffith <richard@geekwright.com> |
20: | * @copyright 2017-2021 XOOPS Project (https://xoops.org) |
21: | * @license GNU GPL 2.0 or later (https://www.gnu.org/licenses/gpl-2.0.html) |
22: | */ |
23: | class Uuid |
24: | { |
25: | // match spec for version 4 UUID as per rfc4122 |
26: | const UUID_REGEX = '/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/'; |
27: | |
28: | /** |
29: | * generate - generate a version 4 (random) UUID |
30: | * |
31: | * Based on comment by pavel.volyntsev(at)gmail at https://php.net/manual/en/function.com-create-guid.php |
32: | * |
33: | * @return string UUID |
34: | * |
35: | * @throws \Exception on insufficient entropy |
36: | */ |
37: | public static function generate() |
38: | { |
39: | $data = random_bytes(16); |
40: | |
41: | $data[6] = chr(ord($data[6]) & 0x0f | 0x40); // set version to 0100 |
42: | $data[8] = chr(ord($data[8]) & 0x3f | 0x80); // set bits 6-7 to 10 |
43: | |
44: | return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)); |
45: | } |
46: | |
47: | /** |
48: | * Pack a UUID into a binary string |
49: | * |
50: | * @param string $uuid a valid UUID |
51: | * |
52: | * @return string packed UUID as a binary string |
53: | * |
54: | * @throws \InvalidArgumentException |
55: | * @throws \UnexpectedValueException |
56: | */ |
57: | public static function packAsBinary($uuid) |
58: | { |
59: | if (!preg_match(static::UUID_REGEX, $uuid)) { |
60: | throw new \InvalidArgumentException('Invalid UUID'); |
61: | } |
62: | $return = pack("H*", str_replace('-', '', $uuid)); |
63: | if (false === $return) { |
64: | throw new \UnexpectedValueException('Packing UUID Failed'); |
65: | } |
66: | return $return; |
67: | } |
68: | |
69: | /** |
70: | * Unpack a UUID stored as a binary string |
71: | * |
72: | * @param string $packedUuid a packed UUID as returned by packAsBinary() |
73: | * |
74: | * @return string unpacked UUID |
75: | * |
76: | * @throws \InvalidArgumentException |
77: | * @throws \UnexpectedValueException |
78: | */ |
79: | public static function unpackBinary($packedUuid) |
80: | { |
81: | if (16 !== strlen($packedUuid)) { |
82: | throw new \InvalidArgumentException('Invalid packed UUID'); |
83: | } |
84: | $return = vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($packedUuid), 4)); |
85: | if (!preg_match(static::UUID_REGEX, $return)) { |
86: | throw new \UnexpectedValueException('Unpacking UUID Failed'); |
87: | } |
88: | return $return; |
89: | } |
90: | } |
91: |