[Uid] Add support for UUIDv6
This commit is contained in:
parent
7dc6da6c26
commit
b705ee1b4b
@ -18,6 +18,7 @@ use Symfony\Component\Uid\UuidV1;
|
||||
use Symfony\Component\Uid\UuidV3;
|
||||
use Symfony\Component\Uid\UuidV4;
|
||||
use Symfony\Component\Uid\UuidV5;
|
||||
use Symfony\Component\Uid\UuidV6;
|
||||
|
||||
class UuidTest extends TestCase
|
||||
{
|
||||
@ -73,6 +74,18 @@ class UuidTest extends TestCase
|
||||
$this->assertInstanceOf(UuidV5::class, $uuid);
|
||||
}
|
||||
|
||||
public function testV6()
|
||||
{
|
||||
$uuid = Uuid::v6();
|
||||
|
||||
$this->assertInstanceOf(UuidV6::class, $uuid);
|
||||
|
||||
$uuid = new UuidV6(substr_replace(self::A_UUID_V1, '6', 14, 1));
|
||||
|
||||
$this->assertSame(85916308548.27832, $uuid->getTime());
|
||||
$this->assertSame('3499710062d0', $uuid->getNode());
|
||||
}
|
||||
|
||||
public function testBinary()
|
||||
{
|
||||
$uuid = new UuidV4(self::A_UUID_V4);
|
||||
|
@ -12,6 +12,8 @@
|
||||
namespace Symfony\Component\Uid;
|
||||
|
||||
/**
|
||||
* A ULID is lexicographically sortable and contains a 48-bit timestamp and 80-bit of crypto-random entropy.
|
||||
*
|
||||
* @see https://github.com/ulid/spec
|
||||
*
|
||||
* @experimental in 5.1
|
||||
|
@ -49,6 +49,7 @@ class Uuid implements \JsonSerializable
|
||||
case UuidV3::TYPE: return new UuidV3($uuid);
|
||||
case UuidV4::TYPE: return new UuidV4($uuid);
|
||||
case UuidV5::TYPE: return new UuidV5($uuid);
|
||||
case UuidV6::TYPE: return new UuidV6($uuid);
|
||||
case NullUuid::TYPE: return new NullUuid();
|
||||
case self::TYPE: return new self($uuid);
|
||||
}
|
||||
@ -76,6 +77,11 @@ class Uuid implements \JsonSerializable
|
||||
return new UuidV5(uuid_generate_sha1($namespace->uuid, $name));
|
||||
}
|
||||
|
||||
final public static function v6(): UuidV6
|
||||
{
|
||||
return new UuidV6();
|
||||
}
|
||||
|
||||
public static function isValid(string $uuid): bool
|
||||
{
|
||||
if (__CLASS__ === static::class) {
|
||||
|
@ -12,7 +12,7 @@
|
||||
namespace Symfony\Component\Uid;
|
||||
|
||||
/**
|
||||
* A v1 UUID contains a 60-bit timestamp and ~60 extra unique bits.
|
||||
* A v1 UUID contains a 60-bit timestamp and 63 extra unique bits.
|
||||
*
|
||||
* @experimental in 5.1
|
||||
*
|
||||
|
60
src/Symfony/Component/Uid/UuidV6.php
Normal file
60
src/Symfony/Component/Uid/UuidV6.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Uid;
|
||||
|
||||
/**
|
||||
* A v6 UUID is lexicographically sortable and contains a 60-bit timestamp and 63 extra unique bits.
|
||||
*
|
||||
* @experimental in 5.1
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
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) {
|
||||
$uuid = uuid_create(UUID_TYPE_TIME);
|
||||
$this->uuid = substr($uuid, 15, 3).substr($uuid, 9, 4).$uuid[0].'-'.substr($uuid, 1, 4).'-6'.substr($uuid, 5, 3).substr($uuid, 18);
|
||||
} else {
|
||||
parent::__construct($uuid);
|
||||
}
|
||||
}
|
||||
|
||||
public function getTime(): float
|
||||
{
|
||||
$time = '0'.substr($this->uuid, 0, 8).substr($this->uuid, 9, 4).substr($this->uuid, 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;
|
||||
}
|
||||
|
||||
public function getNode(): string
|
||||
{
|
||||
return substr($this->uuid, 24);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user