mirror of
https://github.com/ramsey/uuid.git
synced 2026-06-14 15:56:48 +03:00
[ci skip] Continue documentation improvements
This commit is contained in:
+11
-2
@@ -7,11 +7,13 @@ For `ramsey/uuid <https://github.com/ramsey/uuid>`_ |version|. Updated on |today
|
||||
This work is licensed under the `Creative Commons Attribution 4.0 International
|
||||
<https://creativecommons.org/licenses/by/4.0/>`_ license.
|
||||
|
||||
|
||||
Contents
|
||||
--------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:numbered: 1
|
||||
:includehidden:
|
||||
:caption: Contents
|
||||
|
||||
introduction
|
||||
quickstart
|
||||
@@ -21,3 +23,10 @@ This work is licensed under the `Creative Commons Attribution 4.0 International
|
||||
FAQs <faq>
|
||||
reference
|
||||
copyright
|
||||
|
||||
|
||||
Indices and Tables
|
||||
------------------
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`search`
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
Introduction
|
||||
============
|
||||
|
||||
ramsey/uuid is a PHP library for generating and working with [RFC4122]_ version
|
||||
ramsey/uuid is a PHP library for generating and working with `RFC 4122`_ version
|
||||
1, 2, 3, 4, and 5 universally unique identifiers (UUID). ramsey/uuid also
|
||||
supports optional and non-standard features, such as version 6 UUIDs [UUIDV6]_,
|
||||
supports optional and non-standard features, such as `version 6 UUIDs`_,
|
||||
GUIDs, and other approaches for encoding/decoding UUIDs.
|
||||
|
||||
What Is a UUID?
|
||||
@@ -12,7 +12,7 @@ What Is a UUID?
|
||||
|
||||
A universally unique identifier, or UUID, is a 128-bit unsigned integer, usually
|
||||
represented as a hexadecimal string split into five groups with dashes. The most
|
||||
widely-known and used types of UUIDs are defined by [RFC4122]_.
|
||||
widely-known and used types of UUIDs are defined by `RFC 4122`_.
|
||||
|
||||
A UUID, when encoded in hexadecimal string format, looks like:
|
||||
|
||||
@@ -24,3 +24,7 @@ The probability of duplicating a UUID is close to zero, so they are a great
|
||||
choice for generating unique identifiers in distributed systems.
|
||||
|
||||
UUIDs can also be stored in binary format, as a string of 16 bytes.
|
||||
|
||||
|
||||
.. _RFC 4122: https://tools.ietf.org/html/rfc4122
|
||||
.. _version 6 UUIDs: http://gh.peabody.io/uuidv6/
|
||||
|
||||
@@ -7,5 +7,4 @@ Nonstandard UUIDs
|
||||
|
||||
nonstandard/version6
|
||||
nonstandard/comb
|
||||
nonstandard/ordered-time
|
||||
nonstandard/guid
|
||||
|
||||
+7
-6
@@ -58,7 +58,7 @@ the static generation methods.
|
||||
$uuid->getFields()->getVersion()
|
||||
);
|
||||
|
||||
This will return an instance of ``Ramsey\Uuid\Rfc4122\UuidV4``.
|
||||
This will return an instance of :php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV4`.
|
||||
|
||||
.. tip::
|
||||
.. rubric:: Use the Interfaces
|
||||
@@ -66,10 +66,11 @@ This will return an instance of ``Ramsey\Uuid\Rfc4122\UuidV4``.
|
||||
Feel free to use ``instanceof`` to check the specific instance types of
|
||||
UUIDs. However, when using type hints, it's best to use the interfaces.
|
||||
|
||||
The most lenient interface is ``Ramsey\Uuid\UuidInterface``, while
|
||||
``Ramsey\Uuid\Rfc4122\UuidInterface`` ensures the UUIDs you're using conform
|
||||
to the `RFC 4122`_ standard. If you're not sure which one to use, start with
|
||||
the stricter ``Ramsey\Uuid\Rfc4122\UuidInterface``.
|
||||
The most lenient interface is :php:interface:`Ramsey\\Uuid\\UuidInterface`,
|
||||
while :php:interface:`Ramsey\\Uuid\\Rfc4122\\UuidInterface` ensures the
|
||||
UUIDs you're using conform to the `RFC 4122`_ standard. If you're not sure
|
||||
which one to use, start with the stricter
|
||||
:php:interface:`Rfc4122\\UuidInterface <Ramsey\\Uuid\\Rfc4122\\UuidInterface>`.
|
||||
|
||||
ramsey/uuid provides a number of helpful static methods that help you work with
|
||||
and generate most types of UUIDs, without any special customization of the
|
||||
@@ -103,6 +104,6 @@ library.
|
||||
* - :php:meth:`Uuid::fromInteger() <Ramsey\\Uuid\\Uuid::fromInteger>`
|
||||
- Creates a UUID instance from a string integer.
|
||||
* - :php:meth:`Uuid::fromDateTime() <Ramsey\\Uuid\\Uuid::fromDateTime>`
|
||||
- Creates a version 1 UUID instance from a PHP ``DateTimeInterface``.
|
||||
- Creates a version 1 UUID instance from a PHP ``\DateTimeInterface``.
|
||||
|
||||
.. _RFC 4122: https://tools.ietf.org/html/rfc4122
|
||||
|
||||
@@ -22,4 +22,3 @@ Reference
|
||||
reference/exceptions
|
||||
reference/helper
|
||||
reference/name-based-namespaces
|
||||
reference/references
|
||||
|
||||
@@ -21,25 +21,19 @@ Rfc4122\\UuidV2
|
||||
|
||||
.. caution::
|
||||
|
||||
It is important to note that a version 2 UUID suffers from some loss of
|
||||
fidelity of the timestamp, due to replacing the ``time_low`` field with
|
||||
the local identifier. When constructing the timestamp value for date
|
||||
purposes, we replace the local identifier bits with zeros. As a result,
|
||||
the timestamp can be off by a range of 0 to 429.4967295 seconds (or
|
||||
about 7 minutes, 9 seconds, and 496730 microseconds).
|
||||
|
||||
Astute observers might note this value directly corresponds to
|
||||
2\ :sup:`32` -- 1, or ``0xffffffff``. The local identifier is 32-bits,
|
||||
and we have set each of these bits to 0, so the maximum range of
|
||||
timestamp drift is ``0x00000000`` to ``0xffffffff`` (counted in
|
||||
100-nanosecond intervals).
|
||||
It is important to note that version 2 UUIDs suffer from some loss
|
||||
of timestamp precision. See :ref:`rfc4122.version2.timestamp-problems`
|
||||
to learn more.
|
||||
|
||||
:returns: A date object representing the timestamp associated with the UUID
|
||||
:returntype: ``\DateTimeInterface``
|
||||
|
||||
.. php:method:: getLocalDomain()
|
||||
|
||||
:returns: The local domain identifier for this UUID, which is one of :php:const:`Ramsey\\Uuid\\Uuid::DCE_DOMAIN_PERSON`, :php:const:`Ramsey\\Uuid\\Uuid::DCE_DOMAIN_GROUP`, or :php:const:`Ramsey\\Uuid\\Uuid::DCE_DOMAIN_ORG`
|
||||
:returns: The local domain identifier for this UUID, which is one of
|
||||
:php:const:`Ramsey\\Uuid\\Uuid::DCE_DOMAIN_PERSON`,
|
||||
:php:const:`Ramsey\\Uuid\\Uuid::DCE_DOMAIN_GROUP`, or
|
||||
:php:const:`Ramsey\\Uuid\\Uuid::DCE_DOMAIN_ORG`
|
||||
:returntype: ``int``
|
||||
|
||||
.. php:method:: getLocalDomainName()
|
||||
|
||||
@@ -68,3 +68,11 @@ Types
|
||||
A value object representing a timestamp, for type-safety purposes, to ensure
|
||||
that timestamps used by ramsey/uuid are truly timestamp integers and not
|
||||
some other kind of string or integer.
|
||||
|
||||
.. php:method:: getSeconds()
|
||||
|
||||
:returntype: :php:class:`Ramsey\\Uuid\\Type\\Integer`
|
||||
|
||||
.. php:method:: getMicroseconds()
|
||||
|
||||
:returntype: :php:class:`Ramsey\\Uuid\\Type\\Integer`
|
||||
|
||||
+4
-1
@@ -14,7 +14,7 @@ RFC 4122 UUIDs
|
||||
rfc4122/version4
|
||||
rfc4122/version5
|
||||
|
||||
[RFC4122]_ defines five versions of UUID. Each version has different generation
|
||||
`RFC 4122`_ defines five versions of UUID. Each version has different generation
|
||||
algorithms and properties. Which one you choose to use depends on your use-case.
|
||||
You can find out more about their applications on the specific page for that
|
||||
version.
|
||||
@@ -43,3 +43,6 @@ Version 5: Named-based (SHA-1)
|
||||
This version of UUID hashes together a namespace and a name to create a
|
||||
deterministic UUID. The hashing algorithm used is SHA-1. For more details,
|
||||
see :doc:`rfc4122/version5`.
|
||||
|
||||
|
||||
.. _RFC 4122: https://tools.ietf.org/html/rfc4122
|
||||
|
||||
+92
-64
@@ -16,20 +16,19 @@ 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.
|
||||
|
||||
|
||||
Default Mode
|
||||
############
|
||||
|
||||
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, time-based UUID
|
||||
:name: rfc4122.version1.example
|
||||
|
||||
use Ramsey\Uuid\Uuid;
|
||||
|
||||
@@ -55,42 +54,77 @@ It will look something like this:
|
||||
Date: Sun, 01 Mar 2020 23:32:15 +0000
|
||||
Node: 0242ac130003
|
||||
|
||||
After creating a ``UuidInterface`` object from a string (or bytes), you can
|
||||
check to see if it's a version 1 UUID by checking its instance type.
|
||||
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,
|
||||
time-based UUID
|
||||
:name: rfc4122.version1.custom-example
|
||||
|
||||
use Ramsey\Uuid\Rfc4122\UuidV1;
|
||||
use Ramsey\Uuid\Provider\Node\StaticNodeProvider;
|
||||
use Ramsey\Uuid\Type\Hexadecimal;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
|
||||
$uuid = Uuid::fromString('200e43fa-5c14-11ea-bc55-0242ac130003');
|
||||
$nodeProvider = new StaticNodeProvider(new Hexadecimal('121212121212'));
|
||||
$clockSequence = 16383;
|
||||
|
||||
if ($uuid instanceof UuidV1) {
|
||||
printf(
|
||||
"UUID: %s\nVersion: %d\nDate: %s\nNode: %s\n",
|
||||
$uuid->toString(),
|
||||
$uuid->getFields()->getVersion(),
|
||||
$uuid->getDateTime()->format('r'),
|
||||
$uuid->getFields()->getNode()->toString()
|
||||
);
|
||||
}
|
||||
$uuid = Uuid::uuid1($nodeProvider->getNode(), $clockSequence);
|
||||
|
||||
.. tip::
|
||||
Check out the :php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV1` API
|
||||
documentation to learn more about what you can do with a ``UuidV1``
|
||||
instance.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Random or Custom Node
|
||||
#####################
|
||||
.. _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 following example, we use ``RandomNodeProvider`` to generate a random
|
||||
node, which we pass when creating the 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, time-based UUID
|
||||
:name: rfc4122.version1.random-example
|
||||
|
||||
use Ramsey\Uuid\Provider\Node\RandomNodeProvider;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
@@ -99,58 +133,52 @@ node, which we pass when creating the UUID.
|
||||
|
||||
$uuid = Uuid::uuid1($nodeProvider->getNode());
|
||||
|
||||
You may also set the node value of your choice. In this example, we use
|
||||
``StaticNodeProvider`` to do so.
|
||||
|
||||
.. code-block:: php
|
||||
.. _rfc4122.version1.clock:
|
||||
|
||||
use Ramsey\Uuid\Provider\Node\StaticNodeProvider;
|
||||
use Ramsey\Uuid\Type\Hexadecimal;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
What's a Clock Sequence?
|
||||
########################
|
||||
|
||||
$myCustomNode = new Hexadecimal('1234567890ab');
|
||||
$nodeProvider = new StaticNodeProvider($myCustomNode);
|
||||
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.
|
||||
|
||||
$uuid = Uuid::uuid1($nodeProvider->getNode());
|
||||
The clock sequence is the solution to this problem.
|
||||
|
||||
.. attention::
|
||||
According to [RFC4122]_, nodes that do not identify the host 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 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.
|
||||
|
||||
``RandomNodeProvider`` and ``StaticNodeProvider`` of ramsey/uuid set this
|
||||
bit for you, so they’re the easiest to use, but if you use a custom node
|
||||
provider, be sure to set this bit.
|
||||
.. caution::
|
||||
|
||||
See [RFC4122]_, `section 4.5 <https://tools.ietf.org/html/rfc4122#section-4.5>`_,
|
||||
for more details.
|
||||
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.
|
||||
|
||||
|
||||
Using the Factory
|
||||
#################
|
||||
.. _rfc4122.version1.privacy:
|
||||
|
||||
It is possible to override the behavior of ``Uuid::uuid1()`` globally, by
|
||||
overriding values on the ``FeatureSet`` and ``UuidFactory``.
|
||||
Privacy Concerns
|
||||
################
|
||||
|
||||
For example, if you wish to always use a specific node whenever ``Uuid::uuid1()``
|
||||
is called, you may do the following:
|
||||
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.
|
||||
|
||||
.. code-block:: php
|
||||
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`.
|
||||
|
||||
use Ramsey\Uuid\FeatureSet;
|
||||
use Ramsey\Uuid\Provider\Node\StaticNodeProvider;
|
||||
use Ramsey\Uuid\Type\Hexadecimal;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Ramsey\Uuid\UuidFactory;
|
||||
If you do not need an identifier with a timestamp value embedded in it, see
|
||||
:ref:`rfc4122.version4` to learn about random UUIDs.
|
||||
|
||||
$nodeProvider = new StaticNodeProvider(new Hexadecimal('1234567890ab'));
|
||||
|
||||
$featureSet = new FeatureSet();
|
||||
$featureSet->setNodeProvider($nodeProvider);
|
||||
|
||||
$factory = new UuidFactory($featureSet);
|
||||
|
||||
Uuid::setFactory($factory);
|
||||
|
||||
$uuid = Uuid::uuid1();
|
||||
.. _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
|
||||
|
||||
+202
-31
@@ -4,13 +4,23 @@
|
||||
Version 2: DCE Security
|
||||
=======================
|
||||
|
||||
.. tip::
|
||||
|
||||
DCE Security UUIDs are so-called because they were defined as part of the
|
||||
"Authentication and Security Services" for the `Distributed Computing
|
||||
Environment`_ (DCE) in the early 1990s.
|
||||
|
||||
Version 2 UUIDs are not widely used. See :ref:`rfc4122.version2.problems`
|
||||
before deciding whether to use them.
|
||||
|
||||
Like a :ref:`version 1 UUID <rfc4122.version1>`, a version 2 UUID uses the
|
||||
current time, along with the MAC address (or *node*) for a network interface on
|
||||
the local machine. Additionally, a version 2 UUID replaces the low part of the
|
||||
time field with a local identifier such as the user ID or group ID of the local
|
||||
account that created the UUID. This serves three purposes:
|
||||
|
||||
1. You can know *when* the identifier was created (see :ref:`rfc4122.version2.caveats`).
|
||||
1. You can know *when* the identifier was created (see
|
||||
:ref:`rfc4122.version2.timestamp-problems`).
|
||||
2. You can know *where* the identifier was created.
|
||||
3. You can know *who* created the identifier.
|
||||
|
||||
@@ -19,8 +29,13 @@ only is there no need for a central authority to generate identifiers, but you
|
||||
can determine what nodes in your infrastructure created the UUIDs, at what time
|
||||
they were created, and the account on the machine that created them.
|
||||
|
||||
.. code-block::
|
||||
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: Use a domain to generate a version 2, DCE Security UUID
|
||||
:name: rfc4122.version2.example
|
||||
|
||||
use Ramsey\Uuid\Uuid;
|
||||
|
||||
@@ -39,7 +54,7 @@ they were created, and the account on the machine that created them.
|
||||
This will generate a version 2 UUID and print out its string representation, the
|
||||
time the UUID was created, and the node used to create it, as well as the name
|
||||
of the local domain specified and the local domain identifier (in this case, a
|
||||
POSIX UID, automatically obtained from the local machine).
|
||||
`POSIX`_ UID, automatically obtained from the local machine).
|
||||
|
||||
It will look something like this:
|
||||
|
||||
@@ -52,22 +67,110 @@ It will look something like this:
|
||||
Domain: person
|
||||
ID: 501
|
||||
|
||||
.. todo::
|
||||
Just as with version 1 UUIDs, you may provide custom values for version 2 UUIDs,
|
||||
including local identifier, node, and clock sequence.
|
||||
|
||||
Needs discussion on domains (list the domains), ability to specify the node
|
||||
and clock sequence (though the lower 8 bits of the clock sequence, originally
|
||||
a 14-bit integer, are replaced with the domain). In theory, 2^8-1 domains
|
||||
could be defined, but only 3 are registered by the DCE specification.
|
||||
Discuss ability to pass the local identifier.
|
||||
.. code-block:: php
|
||||
:caption: Provide custom identifier, node, and clock sequence to create a
|
||||
version 2, DCE Security UUID
|
||||
:name: rfc4122.version2.custom-example
|
||||
|
||||
.. epigraph::
|
||||
use Ramsey\Uuid\Provider\Node\StaticNodeProvider;
|
||||
use Ramsey\Uuid\Type\Hexadecimal;
|
||||
use Ramsey\Uuid\Type\Integer;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
|
||||
Note that the [domain] can potentially hold values outside the range
|
||||
[0, 2\ :sup:`8` -- 1]; however, the only values currently registered are in
|
||||
the range [0, 2]… [DCE11SEC]_
|
||||
$localId = new Integer(1001);
|
||||
$nodeProvider = new StaticNodeProvider(new Hexadecimal('121212121212'));
|
||||
$clockSequence = 63;
|
||||
|
||||
$uuid = Uuid::uuid2(
|
||||
Uuid::DCE_DOMAIN_ORG,
|
||||
$localId,
|
||||
$nodeProvider->getNode(),
|
||||
$clockSequence
|
||||
);
|
||||
|
||||
.. tip::
|
||||
|
||||
Version 2 UUIDs generated in ramsey/uuid are instances of UuidV2. Check out
|
||||
the :php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV2` API documentation to learn
|
||||
more about what you can do with a UuidV2 instance.
|
||||
|
||||
|
||||
.. _rfc4122.version2.caveats:
|
||||
.. _rfc4122.version2.domains:
|
||||
|
||||
Domains
|
||||
#######
|
||||
|
||||
The *domain* value tells what the local identifier represents.
|
||||
|
||||
If using the *person* or *group* domains, ramsey/uuid will attempt to look up
|
||||
these values from the local machine. On `POSIX`_ systems, it will use ``id -u``
|
||||
and ``id -g``, respectively. On Windows, it will use ``whoami`` and ``wmic``.
|
||||
|
||||
The *org* domain is site-defined. Its intent it to identify the organization
|
||||
that generated the UUID, but since this can have different meanings for
|
||||
different companies and projects, you get to define its value.
|
||||
|
||||
.. list-table:: DCE Security Domains
|
||||
:widths: 30 70
|
||||
:align: center
|
||||
:header-rows: 1
|
||||
:name: rfc4122.version2.table-domains
|
||||
|
||||
* - Constant
|
||||
- Description
|
||||
* - :php:const:`Uuid::DCE_DOMAIN_PERSON <Ramsey\\Uuid\\Uuid::DCE_DOMAIN_PERSON>`
|
||||
- The local identifier refers to a *person* (e.g., UID).
|
||||
* - :php:const:`Uuid::DCE_DOMAIN_GROUP <Ramsey\\Uuid\\Uuid::DCE_DOMAIN_GROUP>`
|
||||
- The local identifier refers to a *group* (e.g., GID).
|
||||
* - :php:const:`Uuid::DCE_DOMAIN_ORG <Ramsey\\Uuid\\Uuid::DCE_DOMAIN_ORG>`
|
||||
- The local identifier refers to an *organization* (this is site-defined).
|
||||
|
||||
.. note::
|
||||
|
||||
According to section 5.2.1.1 of `DCE 1.1: Authentication and Security Services
|
||||
<https://publications.opengroup.org/c311>`_, the domain "can potentially hold
|
||||
values outside the range [0, 2\ :sup:`8` -- 1]; however, the only values
|
||||
currently registered are in the range [0, 2]."
|
||||
|
||||
As a result, ramsey/uuid supports only the *person*, *group*, and *org*
|
||||
domains.
|
||||
|
||||
|
||||
.. _rfc4122.version2.nodes:
|
||||
|
||||
Custom and Random Nodes
|
||||
#######################
|
||||
|
||||
In the :ref:`example above <rfc4122.version2.custom-example>`, we provided a
|
||||
custom node when generating a version 2 UUID. You may also generate random
|
||||
node values.
|
||||
|
||||
To learn more, see the :ref:`rfc4122.version1.custom` and
|
||||
:ref:`rfc4122.version1.random` sections under :ref:`rfc4122.version1`.
|
||||
|
||||
|
||||
.. _rfc4122.version2.clock:
|
||||
|
||||
Clock Sequence
|
||||
##############
|
||||
|
||||
In a version 2 UUID, the clock sequence serves the same purpose as in a version
|
||||
1 UUID. See :ref:`rfc4122.version1.clock` to learn more.
|
||||
|
||||
.. warning::
|
||||
|
||||
The clock sequence in a version 2 UUID is a 6-bit number. It supports values
|
||||
from 0 to 63. This is different from the 14-bit number used by version 1
|
||||
UUIDs.
|
||||
|
||||
See :ref:`rfc4122.version2.uniqueness-problems` to understand how this
|
||||
affects version 2 UUIDs.
|
||||
|
||||
|
||||
.. _rfc4122.version2.problems:
|
||||
|
||||
Problems With Version 2 UUIDs
|
||||
#############################
|
||||
@@ -75,27 +178,95 @@ Problems With Version 2 UUIDs
|
||||
Version 2 UUIDs can be useful for the data they contain. However, there are
|
||||
trade-offs in choosing to use them.
|
||||
|
||||
|
||||
.. _rfc4122.version2.privacy-problems:
|
||||
|
||||
Privacy
|
||||
-------
|
||||
|
||||
Unless using a randomly-generated node, version 2 UUIDs use the MAC address for
|
||||
a local hardware interface as the node value. In addition, they use a local
|
||||
identifier --- usually an account or group ID. Some may consider the use of
|
||||
these identifying features a breach of privacy. The use of a timestamp further
|
||||
complicates the issue, since these UUIDs could be used to identify a user
|
||||
account on a specific machine at a specific time.
|
||||
|
||||
If you don't need an identifier with a local identifier and timestamp value
|
||||
embedded in it, see :ref:`rfc4122.version4` to learn about random UUIDs.
|
||||
|
||||
|
||||
.. _rfc4122.version2.uniqueness-problems:
|
||||
|
||||
Limited Uniqueness
|
||||
------------------
|
||||
|
||||
With the inclusion of the local identifier and domain comes a serious limitation
|
||||
in the amount of unique UUIDs that may be created. This is because:
|
||||
|
||||
1. The local identifier replaces the lower 32 bits of the timestamp.
|
||||
2. The domain replaces the lower 8 bits of the clock sequence.
|
||||
|
||||
As a result, the timestamp advances --- the clock *ticks* --- only once every
|
||||
429.49 seconds (about 7 minutes). This means the clock sequence is important to
|
||||
ensure uniqueness, but since the clock sequence is only 6 bits, compared to 14
|
||||
bits for version 1 UUIDs, **only 64 unique UUIDs per combination of node,
|
||||
domain, and identifier may be generated per 7-minute tick of the clock**.
|
||||
|
||||
You can overcome this lack of uniqueness by using a
|
||||
:ref:`random node <rfc4122.version2.nodes>`, which provides 47 bits of
|
||||
randomness to the UUID --- after setting the unicast/multicast bit (see
|
||||
discussion on :ref:`rfc4122.version1.custom`) --- increasing the number of UUIDs
|
||||
per 7-minute clock tick to 2\ :sup:`53` (or 9,007,199,254,740,992), at the
|
||||
expense of remaining locally unique.
|
||||
|
||||
.. note::
|
||||
|
||||
This lack of uniqueness did not present a problem for DCE, since:
|
||||
|
||||
[T]he security architecture of DCE depends upon the uniqueness of
|
||||
security-version UUIDs *only within the context of a cell*; that is,
|
||||
only within the context of the local [Registration Service's]
|
||||
(persistent) datastore, and that degree of uniqueness can be guaranteed
|
||||
by the RS itself (namely, the RS maintains state in its datastore, in
|
||||
the sense that it can always check that every UUID it maintains is
|
||||
different from all other UUIDs it maintains). In other words, while
|
||||
security-version UUIDs are (like all UUIDs) specified to be "globally
|
||||
unique in space and time", security is not compromised if they are
|
||||
merely "locally unique per cell".
|
||||
|
||||
-- `DCE 1.1: Authentication and Security Services, section 5.2.1.1
|
||||
<https://publications.opengroup.org/c311>`_
|
||||
|
||||
|
||||
.. _rfc4122.version2.timestamp-problems:
|
||||
|
||||
Lossy Timestamps
|
||||
----------------
|
||||
|
||||
Version 2 UUIDs are first generated in the same way as version 1 UUIDs, but then
|
||||
the low part of the timestamp (the ``time_low`` field) is replaced by a 32-bit
|
||||
integer that represents a local identifier, which refers to
|
||||
Version 2 UUIDs are generated in the same way as version 1 UUIDs, but the low
|
||||
part of the timestamp (the ``time_low`` field) is replaced by a 32-bit integer
|
||||
that represents a local identifier. Because of this, not only do version 2 UUIDs
|
||||
have :ref:`limited uniqueness <rfc4122.version2.uniqueness-problems>`, but they
|
||||
also lack time precision.
|
||||
|
||||
It is important to note that a version 2 UUID suffers from some loss of
|
||||
fidelity of the timestamp, due to replacing the time_low field with the
|
||||
local identifier. When constructing the timestamp value for date
|
||||
purposes, we replace the local identifier bits with zeros. As a result,
|
||||
the timestamp can be off by a range of 0 to 429.4967295 seconds (or 7
|
||||
minutes, 9 seconds, and 496730 microseconds).
|
||||
When reconstructing the timestamp to return a ``\DateTimeInterface`` instance
|
||||
from :php:meth:`UuidV2::getDateTime() <Ramsey\\Uuid\\Rfc4122\\UuidV2::getDateTime>`,
|
||||
we replace the 32 lower bits of the timestamp with zeros, since the local
|
||||
identifier should not be part of the timestamp. This results in a loss of
|
||||
precision, causing the timestamp to be off by a range of 0 to 429.4967295
|
||||
seconds (or 7 minutes, 9 seconds, and 496,730 microseconds).
|
||||
|
||||
Astute observers might note this value directly corresponds to
|
||||
2\ :sup:`32` -- 1, or ``0xffffffff``. The local identifier is 32-bits, and we
|
||||
have set each of these bits to 0, so the maximum range of timestamp drift is
|
||||
``0x00000000`` to ``0xffffffff`` (counted in 100-nanosecond intervals).
|
||||
When using version 2 UUIDs, treat the timestamp as an approximation. At worst,
|
||||
it could be off by about 7 minutes.
|
||||
|
||||
Limited Unique UUIDs
|
||||
--------------------
|
||||
.. hint::
|
||||
|
||||
With the inclusion of the local identifier comes a serious limitation in the
|
||||
amount of unique UUIDs that may be created.
|
||||
If the value 429.4967295 looks familiar, it's because it directly
|
||||
corresponds to 2\ :sup:`32` -- 1, or ``0xffffffff``. The local identifier is
|
||||
32-bits, and we have set each of these bits to 0, so the maximum range of
|
||||
timestamp drift is ``0x00000000`` to ``0xffffffff`` (counted in
|
||||
100-nanosecond intervals).
|
||||
|
||||
|
||||
.. _Distributed Computing Environment: https://en.wikipedia.org/wiki/Distributed_Computing_Environment
|
||||
.. _POSIX: https://en.wikipedia.org/wiki/POSIX
|
||||
|
||||
@@ -6,7 +6,7 @@ Version 3: Name-based (MD5)
|
||||
|
||||
.. attention::
|
||||
|
||||
[RFC4122]_ states, "If backward compatibility is not an issue, SHA-1 is
|
||||
`RFC 4122`_ states, "If backward compatibility is not an issue, SHA-1 is
|
||||
preferred." As a result, the use of :ref:`version 5 UUIDs
|
||||
<rfc4122.version5>` is preferred over version 3 UUIDs, unless you have a
|
||||
specific use-case for version 3 UUIDs.
|
||||
@@ -18,7 +18,7 @@ Version 3: Name-based (MD5)
|
||||
<rfc4122.version5>`. The only difference is the hashing algorithm used to
|
||||
generate the UUID.
|
||||
|
||||
Version 3 UUIDs use MD5 [RFC1321]_ as the hashing algorithm for combining
|
||||
Version 3 UUIDs use `MD5`_ as the hashing algorithm for combining
|
||||
the namespace and the name.
|
||||
|
||||
Due to the use of a different hashing algorithm, version 3 UUIDs generated with
|
||||
@@ -58,7 +58,11 @@ With this custom namespace, the version 3 UUID for the name "widget/1234567890"
|
||||
will always be ``53564aa3-4154-3ca5-ac90-dba59dc7d3cb``.
|
||||
|
||||
.. tip::
|
||||
Version 3 UUIDs generated in ramsey/uuid are instances of
|
||||
``Ramsey\Uuid\Rfc4122\UuidV3``. Check out the
|
||||
:php:interface:`Ramsey\\Uuid\\Rfc4122\\UuidInterface` API documentation to
|
||||
learn more about what you can do with a ``UuidV3`` instance.
|
||||
|
||||
Version 3 UUIDs generated in ramsey/uuid are instances of UuidV3. Check out
|
||||
the :php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV3` API documentation to learn
|
||||
more about what you can do with a UuidV3 instance.
|
||||
|
||||
|
||||
.. _RFC 4122: https://tools.ietf.org/html/rfc4122
|
||||
.. _MD5: https://en.wikipedia.org/wiki/MD5
|
||||
|
||||
+11
-15
@@ -9,9 +9,9 @@ randomly-generated and do not contain any information about the time they are
|
||||
created or the machine that generated them. If you don't care about this
|
||||
information, then a version 4 UUID might be perfect for your needs.
|
||||
|
||||
To generate a version 4 UUID, you may use the ``Uuid::uuid4()`` static method.
|
||||
|
||||
.. code-block:: php
|
||||
:caption: Generate a version 4, random UUID
|
||||
:name: rfc4122.version4.example
|
||||
|
||||
use Ramsey\Uuid\Uuid;
|
||||
|
||||
@@ -23,21 +23,17 @@ To generate a version 4 UUID, you may use the ``Uuid::uuid4()`` static method.
|
||||
$uuid->getFields()->getVersion()
|
||||
);
|
||||
|
||||
After creating a ``UuidInterface`` object from a string (or bytes), you can
|
||||
check to see if it's a version 4 UUID by checking its instance type.
|
||||
This will generate a version 4 UUID and print out its string representation.
|
||||
It will look something like this:
|
||||
|
||||
.. code-block:: php
|
||||
.. code-block:: text
|
||||
|
||||
use Ramsey\Uuid\Rfc4122\UuidV4;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
UUID: 1ee9aa1b-6510-4105-92b9-7171bb2f3089
|
||||
Version: 4
|
||||
|
||||
$uuid = Uuid::fromString('6b8d3b65-a527-49d5-b6dc-cf195877feef');
|
||||
|
||||
if ($uuid instanceof UuidV4) {
|
||||
printf("%s is a version 4 UUID!\n", $uuid->toString());
|
||||
}
|
||||
|
||||
.. tip::
|
||||
Check out the :php:interface:`Ramsey\\Uuid\\Rfc4122\\UuidInterface` API
|
||||
documentation to learn more about what you can do with a ``UuidV4``
|
||||
instance.
|
||||
|
||||
Version 4 UUIDs generated in ramsey/uuid are instances of UuidV4. Check out
|
||||
the :php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV4` API documentation to learn
|
||||
more about what you can do with a UuidV4 instance.
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
Version 5: Name-based (SHA-1)
|
||||
=============================
|
||||
|
||||
.. caution::
|
||||
.. danger::
|
||||
|
||||
Since :ref:`version 3 <rfc4122.version3>` and version 5 UUIDs essentially
|
||||
use a *salt* (the namespace) to hash data, it may be tempting to use them to
|
||||
hash passwords. **DO NOT do this under any circumstances!** You should not
|
||||
@@ -36,7 +37,8 @@ to the namespace they're created in. RFC 4122 defines some
|
||||
for URLs.
|
||||
|
||||
.. note::
|
||||
Version 5 UUIDs use [SHA1]_ as the hashing algorithm for combining the
|
||||
|
||||
Version 5 UUIDs use `SHA-1`_ as the hashing algorithm for combining the
|
||||
namespace and the name.
|
||||
|
||||
.. code-block:: php
|
||||
@@ -53,10 +55,10 @@ will always be ``a8f6ae40-d8a7-58f0-be05-a22f94eca9ec``. See for yourself. Run
|
||||
the code above, and you'll see it always generates the same UUID.
|
||||
|
||||
.. tip::
|
||||
Version 5 UUIDs generated in ramsey/uuid are instances of
|
||||
``Ramsey\Uuid\Rfc4122\UuidV5``. Check out the
|
||||
:php:interface:`Ramsey\\Uuid\\Rfc4122\\UuidInterface` API documentation to
|
||||
learn more about what you can do with a ``UuidV5`` instance.
|
||||
|
||||
Version 5 UUIDs generated in ramsey/uuid are instances of UuidV5. Check out
|
||||
the :php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV5` API documentation to learn
|
||||
more about what you can do with a UuidV5 instance.
|
||||
|
||||
|
||||
.. _rfc4122.version5.custom-namespaces:
|
||||
@@ -100,3 +102,6 @@ will always be ``a35477ae-bfb1-5f2e-b5a4-4711594d855f``.
|
||||
We can publish this namespace, allowing others to use it to generate identifiers
|
||||
for widgets. When two or more systems try to reference the same widget, they'll
|
||||
end up generating the same identifier for it, which is exactly what we want.
|
||||
|
||||
|
||||
.. _SHA-1: https://en.wikipedia.org/wiki/SHA-1
|
||||
|
||||
@@ -37,9 +37,11 @@ use const STR_PAD_LEFT;
|
||||
* 128-bit unsigned integer
|
||||
*
|
||||
* @link https://publications.opengroup.org/c311 DCE 1.1: Authentication and Security Services
|
||||
* @link https://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01 DCE 1.1, §5.2.1.1
|
||||
* @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1, §11.5.1.1
|
||||
* @link https://github.com/google/uuid Go package for UUIDs based on RFC 4122 and DCE 1.1: Auth and Security Services
|
||||
* @link https://publications.opengroup.org/c706 DCE 1.1: Remote Procedure Call
|
||||
* @link https://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01 DCE 1.1: Auth & Sec, §5.2.1.1
|
||||
* @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1: Auth & Sec, §11.5.1.1
|
||||
* @link https://pubs.opengroup.org/onlinepubs/9629399/apdxa.htm DCE 1.1: RPC, Appendix A
|
||||
* @link https://github.com/google/uuid Go package for UUIDs (includes DCE implementation)
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user