diff --git a/src/Symfony/Component/Uid/BinaryUtil.php b/src/Symfony/Component/Uid/BinaryUtil.php index 812dd4f665..3418d59ee1 100644 --- a/src/Symfony/Component/Uid/BinaryUtil.php +++ b/src/Symfony/Component/Uid/BinaryUtil.php @@ -36,6 +36,12 @@ class BinaryUtil 'u' => 52, 'v' => 53, 'w' => 54, 'x' => 55, 'y' => 56, 'z' => 57, ]; + // https://tools.ietf.org/html/rfc4122#section-4.1.4 + // 0x01b21dd213814000 is the number of 100-ns intervals between the + // UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00. + private const TIME_OFFSET_INT = 0x01b21dd213814000; + private const TIME_OFFSET_COM = "\xfe\x4d\xe2\x2d\xec\x7e\xc0\x00"; + public static function toBase(string $bytes, array $map): string { $base = \strlen($alphabet = $map['']); @@ -107,4 +113,17 @@ class BinaryUtil return $a; } + + public static function timeToFloat(string $time): float + { + if (\PHP_INT_SIZE >= 8) { + return (hexdec($time) - self::TIME_OFFSET_INT) / 10000000; + } + + $time = str_pad(hex2bin($time), 8, "\0", STR_PAD_LEFT); + $time = self::add($time, self::TIME_OFFSET_COM); + $time[0] = $time[0] & "\x7F"; + + return self::toBase($time, self::BASE10) / 10000000; + } } diff --git a/src/Symfony/Component/Uid/Uuid.php b/src/Symfony/Component/Uid/Uuid.php index 1e8a7d9c10..1fe335e4bb 100644 --- a/src/Symfony/Component/Uid/Uuid.php +++ b/src/Symfony/Component/Uid/Uuid.php @@ -76,12 +76,8 @@ class Uuid extends AbstractUid { // don't use uuid_generate_md5(), some versions are buggy $uuid = md5(hex2bin(str_replace('-', '', $namespace->uid)).$name, true); - $uuid[8] = $uuid[8] & "\x3F" | "\x80"; - $uuid = substr_replace(bin2hex($uuid), '-', 8, 0); - $uuid = substr_replace($uuid, '-3', 13, 1); - $uuid = substr_replace($uuid, '-', 18, 0); - return new UuidV3(substr_replace($uuid, '-', 23, 0)); + return new UuidV3(self::format($uuid, '-3')); } final public static function v4(): UuidV4 @@ -93,12 +89,8 @@ class Uuid extends AbstractUid { // don't use uuid_generate_sha1(), some versions are buggy $uuid = substr(sha1(hex2bin(str_replace('-', '', $namespace->uid)).$name, true), 0, 16); - $uuid[8] = $uuid[8] & "\x3F" | "\x80"; - $uuid = substr_replace(bin2hex($uuid), '-', 8, 0); - $uuid = substr_replace($uuid, '-5', 13, 1); - $uuid = substr_replace($uuid, '-', 18, 0); - return new UuidV5(substr_replace($uuid, '-', 23, 0)); + return new UuidV5(self::format($uuid, '-5')); } final public static function v6(): UuidV6 @@ -133,4 +125,14 @@ class Uuid extends AbstractUid return parent::compare($other); } + + private static function format(string $uuid, string $version): string + { + $uuid[8] = $uuid[8] & "\x3F" | "\x80"; + $uuid = substr_replace(bin2hex($uuid), '-', 8, 0); + $uuid = substr_replace($uuid, $version, 13, 1); + $uuid = substr_replace($uuid, '-', 18, 0); + + return substr_replace($uuid, '-', 23, 0); + } } diff --git a/src/Symfony/Component/Uid/UuidV1.php b/src/Symfony/Component/Uid/UuidV1.php index 3694e0c907..12ed39a6ff 100644 --- a/src/Symfony/Component/Uid/UuidV1.php +++ b/src/Symfony/Component/Uid/UuidV1.php @@ -22,12 +22,6 @@ class UuidV1 extends Uuid { protected const TYPE = UUID_TYPE_TIME; - // https://tools.ietf.org/html/rfc4122#section-4.1.4 - // 0x01b21dd213814000 is the number of 100-ns intervals between the - // UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00. - private const TIME_OFFSET_INT = 0x01b21dd213814000; - private const TIME_OFFSET_COM = "\xfe\x4d\xe2\x2d\xec\x7e\xc0\x00"; - public function __construct(string $uuid = null) { if (null === $uuid) { @@ -41,15 +35,7 @@ class UuidV1 extends Uuid { $time = '0'.substr($this->uid, 15, 3).substr($this->uid, 9, 4).substr($this->uid, 0, 8); - if (\PHP_INT_SIZE >= 8) { - return (hexdec($time) - self::TIME_OFFSET_INT) / 10000000; - } - - $time = str_pad(hex2bin($time), 8, "\0", STR_PAD_LEFT); - $time = BinaryUtil::add($time, self::TIME_OFFSET_COM); - $time[0] = $time[0] & "\x7F"; - - return BinaryUtil::toBase($time, BinaryUtil::BASE10) / 10000000; + return BinaryUtil::timeToFloat($time); } public function getNode(): string diff --git a/src/Symfony/Component/Uid/UuidV6.php b/src/Symfony/Component/Uid/UuidV6.php index d479b8b0f8..2d30d8820d 100644 --- a/src/Symfony/Component/Uid/UuidV6.php +++ b/src/Symfony/Component/Uid/UuidV6.php @@ -22,12 +22,6 @@ class UuidV6 extends Uuid { protected const TYPE = 6; - // https://tools.ietf.org/html/rfc4122#section-4.1.4 - // 0x01b21dd213814000 is the number of 100-ns intervals between the - // UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00. - private const TIME_OFFSET_INT = 0x01b21dd213814000; - private const TIME_OFFSET_COM = "\xfe\x4d\xe2\x2d\xec\x7e\xc0\x00"; - public function __construct(string $uuid = null) { if (null === $uuid) { @@ -42,15 +36,7 @@ class UuidV6 extends Uuid { $time = '0'.substr($this->uid, 0, 8).substr($this->uid, 9, 4).substr($this->uid, 15, 3); - if (\PHP_INT_SIZE >= 8) { - return (hexdec($time) - self::TIME_OFFSET_INT) / 10000000; - } - - $time = str_pad(hex2bin($time), 8, "\0", STR_PAD_LEFT); - $time = BinaryUtil::add($time, self::TIME_OFFSET_COM); - $time[0] = $time[0] & "\x7F"; - - return BinaryUtil::toBase($time, BinaryUtil::BASE10) / 10000000; + return BinaryUtil::timeToFloat($time); } public function getNode(): string