Version 6: Reordered Time¶
Note
Version 6, reordered time UUIDs are a new format of UUID, proposed in an Internet-Draft under review at the IETF. While the draft is still going through the IETF process, the version 6 format is not expected to change in any way that breaks compatibility.
Attention
If you need a time-based UUID, and you don’t need the other features included in version 6 UUIDs, we recommend using version 7 UUIDs.
Version 6 UUIDs solve two problems that have long existed with the use of version 1 UUIDs:
Scattered database records
Inability to sort by an identifier in a meaningful way (i.e., insert order)
To overcome these issues, we need the ability to generate UUIDs that are monotonically increasing while still providing all the benefits of version 1 UUIDs.
Version 6 UUIDs do this by storing the time in standard byte order, instead of breaking it up and rearranging the time bytes, according to the RFC 4122 definition. All other fields remain the same, and the version maintains its position, according to RFC 4122.
In all other ways, version 6 UUIDs function like version 1 UUIDs.
Tip
Prior to version 4.0.0, ramsey/uuid provided a solution for this with the ordered-time codec. Use of the ordered-time codec is still valid and acceptable. However, you may replace UUIDs generated using the ordered-time codec with version 6 UUIDs. Keep reading to find out how.
use Ramsey\Uuid\Uuid;
$uuid = Uuid::uuid6();
printf(
"UUID: %s\nVersion: %d\nDate: %s\nNode: %s\n",
$uuid->toString(),
$uuid->getFields()->getVersion(),
$uuid->getDateTime()->format('r'),
$uuid->getFields()->getNode()->toString()
);
This will generate a version 6 UUID and print out its string representation, the time the UUID was created, and the node used to create the UUID.
It will look something like this:
UUID: 1ea60f56-b67b-61fc-829a-0242ac130003
Version: 6
Date: Sun, 08 Mar 2020 04:29:37 +0000
Node: 0242ac130003
You may provide custom values for version 6 UUIDs, including node and clock sequence.
use Ramsey\Uuid\Provider\Node\StaticNodeProvider;
use Ramsey\Uuid\Type\Hexadecimal;
use Ramsey\Uuid\Uuid;
$nodeProvider = new StaticNodeProvider(new Hexadecimal('121212121212'));
$clockSequence = 16383;
$uuid = Uuid::uuid6($nodeProvider->getNode(), $clockSequence);
Tip
Version 6 UUIDs generated in ramsey/uuid are instances of UuidV6. Check out
the Ramsey\Uuid\Rfc4122\UuidV6
API documentation to
learn more about what you can do with a UuidV6 instance.
Custom and Random Nodes¶
In the example above, we provided a custom node when generating a version 6 UUID. You may also generate random node values.
To learn more, see the Providing a Custom Node and Generating a Random Node sections under Version 1: Gregorian Time.
Clock Sequence¶
In a version 6 UUID, the clock sequence serves the same purpose as in a version 1 UUID. See What’s a Clock Sequence? to learn more.
Version 1-to-6 Conversion¶
It is possible to convert back-and-forth between version 6 and version 1 UUIDs.
use Ramsey\Uuid\Rfc4122\UuidV1;
use Ramsey\Uuid\Rfc4122\UuidV6;
use Ramsey\Uuid\Uuid;
$uuid1 = Uuid::fromString('3960c5d8-60f8-11ea-bc55-0242ac130003');
if ($uuid1 instanceof UuidV1) {
$uuid6 = UuidV6::fromUuidV1($uuid1);
}
use Ramsey\Uuid\Rfc4122\UuidV6;
use Ramsey\Uuid\Uuid;
$uuid6 = Uuid::fromString('1ea60f83-960c-65d8-bc55-0242ac130003');
if ($uuid6 instanceof UuidV6) {
$uuid1 = $uuid6->toUuidV1();
}
Ordered-time to Version 6 Conversion¶
You may convert UUIDs previously generated and stored using the ordered-time codec into version 6 UUIDs.
Caution
If you perform this conversion, the bytes and string representation of your UUIDs will change. This will break any software that expects your identifiers to be fixed.
use Ramsey\Uuid\Codec\OrderedTimeCodec;
use Ramsey\Uuid\Rfc4122\UuidV1;
use Ramsey\Uuid\Rfc4122\UuidV6;
use Ramsey\Uuid\UuidFactory;
// The bytes of a version 1 UUID previously stored in some datastore
// after encoding to bytes with the OrderedTimeCodec.
$bytes = hex2bin('11ea60faf17c8af6ad23acde48001122');
$factory = new UuidFactory();
$codec = new OrderedTimeCodec($factory->getUuidBuilder());
$factory->setCodec($codec);
$orderedTimeUuid = $factory->fromBytes($bytes);
if ($orderedTimeUuid instanceof UuidV1) {
$uuid6 = UuidV6::fromUuidV1($orderedTimeUuid);
}
Privacy Concerns¶
Like version 1 UUIDs, version 6 UUIDs use a MAC address from a local hardware network interface. This means it is possible to uniquely identify the machine on which a version 6 UUID was created.
If the value provided by the timestamp of a version 6 UUID is important to you, but you do not wish to expose the interface address of any of your local machines, see Custom and Random Nodes.
If you do not need an identifier with a node value embedded in it, but you still need the benefit of a monotonically increasing unique identifier, see Version 7: Unix Epoch Time.