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