| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- .. _rfc4122.version1:
- =========================
- Version 1: Gregorian Time
- =========================
- .. attention::
- If you need a time-based UUID, and you don't need the other features
- included in version 1 UUIDs, we recommend using
- :ref:`version 7 UUIDs <rfc4122.version7>`.
- A version 1 UUID uses the current time, along with the MAC address (or *node*)
- for a network interface on the local machine. This serves two purposes:
- 1. You can know *when* the identifier was created.
- 2. You can know *where* the identifier was created.
- In a distributed system, these two pieces of information can be valuable. Not
- only is there no need for a central authority to generate identifiers, but you
- can determine what nodes in your infrastructure created the UUIDs and at what
- time.
- .. tip::
- It is also possible to use a **randomly-generated node**, rather than a
- hardware address. This is useful for when you don't want to leak machine
- information, while still using a UUID based on time. Keep reading to find
- out how.
- By default, ramsey/uuid will attempt to look up a MAC address for the machine it
- is running on, using this value as the node. If it cannot find a MAC address, it
- will generate a random node.
- .. code-block:: php
- :caption: Generate a version 1, Gregorian time UUID
- :name: rfc4122.version1.example
- use Ramsey\Uuid\Uuid;
- $uuid = Uuid::uuid1();
- 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 1 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:
- .. code-block:: text
- UUID: e22e1622-5c14-11ea-b2f3-0242ac130003
- Version: 1
- Date: Sun, 01 Mar 2020 23:32:15 +0000
- Node: 0242ac130003
- You may provide custom values for version 1 UUIDs, including node and clock
- sequence.
- .. code-block:: php
- :caption: Provide custom node and clock sequence to create a version 1,
- Gregorian time UUID
- :name: rfc4122.version1.custom-example
- 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::uuid1($nodeProvider->getNode(), $clockSequence);
- .. tip::
- Version 1 UUIDs generated in ramsey/uuid are instances of UuidV1. Check out
- the :php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV1` API documentation to learn
- more about what you can do with a UuidV1 instance.
- .. _rfc4122.version1.custom:
- Providing a Custom Node
- #######################
- You may override the default behavior by passing your own node value when
- generating a version 1 UUID.
- In the :ref:`example above <rfc4122.version1.custom-example>`, we saw how to
- pass a custom node and clock sequence. An interesting thing to note about the
- example is its use of StaticNodeProvider. Why didn't we pass in a
- :php:class:`Hexadecimal <Ramsey\\Uuid\\Type\\Hexadecimal>` value, instead?
- According to `RFC 4122, section 4.5`_, node values that do not identify the
- host --- in other words, our own custom node value --- should set the
- unicast/multicast bit to one (1). This bit will never be set in IEEE 802
- addresses obtained from network cards, so it helps to distinguish it from a
- hardware MAC address.
- The StaticNodeProvider sets this bit for you. This is why we used it rather
- than providing a :php:class:`Hexadecimal <Ramsey\\Uuid\\Type\\Hexadecimal>`
- value directly.
- Recall from the example that the node value we set was ``121212121212``, but if
- you take a look at this value with ``$uuid->getFields()->getNode()->toString()``,
- it becomes:
- .. code-block:: text
- 131212121212
- That's a result of this bit being set by the StaticNodeProvider.
- .. _rfc4122.version1.random:
- Generating a Random Node
- ########################
- Instead of providing a custom node, you may also generate a random node each
- time you generate a version 1 UUID. The RandomNodeProvider may be used to
- generate a random node value, and like the StaticNodeProvider, it also sets the
- unicast/multicast bit for you.
- .. code-block:: php
- :caption: Provide a random node value to create a version 1, Gregorian time UUID
- :name: rfc4122.version1.random-example
- use Ramsey\Uuid\Provider\Node\RandomNodeProvider;
- use Ramsey\Uuid\Uuid;
- $nodeProvider = new RandomNodeProvider();
- $uuid = Uuid::uuid1($nodeProvider->getNode());
- .. _rfc4122.version1.clock:
- What's a Clock Sequence?
- ########################
- The clock sequence part of a version 1 UUID helps prevent collisions. Since this
- UUID is based on a timestamp and a machine node value, it is possible for
- collisions to occur for multiple UUIDs generated within the same microsecond on
- the same machine.
- The clock sequence is the solution to this problem.
- The clock sequence is a 14-bit number --- this supports values from 0 to 16,383
- --- which means it should be possible to generate up to 16,384 UUIDs per
- microsecond with the same node value, before hitting a collision.
- .. caution::
- ramsey/uuid does not use *stable storage* for clock sequence values.
- Instead, all clock sequences are randomly-generated. If you are generating
- a lot of version 1 UUIDs every microsecond, it is possible to hit collisions
- because of the random values. If this is the case, you should use your own
- mechanism for generating clock sequence values, to ensure against
- randomly-generated duplicates.
- See `section 4.2 of RFC 4122`_, for more information.
- .. _rfc4122.version1.privacy:
- Privacy Concerns
- ################
- As discussed earlier in this section, version 1 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 1 UUID was created.
- If the value provided by the timestamp of a version 1 UUID is important to you,
- but you do not wish to expose the interface address of any of your local
- machines, see :ref:`rfc4122.version1.random` or :ref:`rfc4122.version1.custom`.
- If you do not need an identifier with a timestamp value embedded in it, see
- :ref:`rfc4122.version4` to learn about random UUIDs.
- .. _RFC 4122: https://tools.ietf.org/html/rfc4122
- .. _RFC 4122, section 4.5: https://tools.ietf.org/html/rfc4122#section-4.5
- .. _section 4.2 of RFC 4122: https://tools.ietf.org/html/rfc4122#section-4.2
|