| 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: |