diff --git a/docs/reference.rst b/docs/reference.rst index 3bf58b0..31b5489 100644 --- a/docs/reference.rst +++ b/docs/reference.rst @@ -10,5 +10,7 @@ Reference reference/uuid reference/rfc4122-uuidinterface reference/rfc4122-fieldsinterface + reference/rfc4122-uuidv1 + reference/exceptions reference/helper reference/name-based-namespaces diff --git a/docs/reference/exceptions.rst b/docs/reference/exceptions.rst new file mode 100644 index 0000000..7790053 --- /dev/null +++ b/docs/reference/exceptions.rst @@ -0,0 +1,83 @@ +.. _reference.exceptions: + +========== +Exceptions +========== + +.. php:namespace:: Ramsey\Uuid\Exception + +.. php:exception:: BuilderNotFoundException + + Extends ``\RuntimeException``. + + Thrown to indicate that no suitable UUID builder could be found. + +.. php:exception:: DateTimeException + + Extends ``\RuntimeException``. + + Thrown to indicate that the PHP DateTime extension encountered an + exception or error. + +.. php:exception:: DceSecurityException + + Extends ``\RuntimeException``. + + Thrown to indicate an exception occurred while dealing with DCE Security + (version 2) UUIDs + +.. php:exception:: InvalidArgumentException + + Extends ``\InvalidArgumentException``. + + Thrown to indicate that the argument received is not valid. + +.. php:exception:: InvalidBytesException + + Extends ``\RuntimeException``. + + Thrown to indicate that the bytes being operated on are invalid in some way. + +.. php:exception:: InvalidUuidStringException + + Extends :php:exc:`Ramsey\\Uuid\\Exception\\InvalidArgumentException`. + + Thrown to indicate that the string received is not a valid UUID. + +.. php:exception:: NameException + + Extends ``\RuntimeException``. + + Thrown to indicate that an error occurred while attempting to hash a + namespace and name + +.. php:exception:: NodeException + + Extends ``\RuntimeException``. + + Thrown to indicate that attempting to fetch or create a node ID encountered + an error. + +.. php:exception:: RandomSourceException + + Extends ``\RuntimeException``. + + Thrown to indicate that the source of random data encountered an error. + +.. php:exception:: TimeSourceException + + Extends ``\RuntimeException``. + + Thrown to indicate that the source of time encountered an error. + +.. php:exception:: UnableToBuildUuidException + + Extends ``\RuntimeException``. + + Thrown to indicate a builder is unable to build a UUID. + +.. php:exception:: UnsupportedOperationException + + Extends ``\LogicException``. + + Thrown to indicate that the requested operation is not supported. diff --git a/docs/reference/name-based-namespaces.rst b/docs/reference/name-based-namespaces.rst index 0792fc6..7c56438 100644 --- a/docs/reference/name-based-namespaces.rst +++ b/docs/reference/name-based-namespaces.rst @@ -17,7 +17,7 @@ interesting name spaces." * - :php:const:`Uuid::NAMESPACE_DNS ` - The name string is a fully-qualified domain name. * - :php:const:`Uuid::NAMESPACE_URL ` - - The name string is URL. + - The name string is a URL. * - :php:const:`Uuid::NAMESPACE_OID ` - The name string is an `ISO object identifier (OID)`_. * - :php:const:`Uuid::NAMESPACE_X500 ` diff --git a/docs/reference/rfc4122-uuidv1.rst b/docs/reference/rfc4122-uuidv1.rst new file mode 100644 index 0000000..6c7649c --- /dev/null +++ b/docs/reference/rfc4122-uuidv1.rst @@ -0,0 +1,19 @@ +.. _reference.rfc4122.uuidv1: + +=============== +Rfc4122\\UuidV1 +=============== + +.. php:namespace:: Ramsey\Uuid\Rfc4122 + +.. php:class:: UuidV1 + + Implements :php:interface:`Ramsey\\Uuid\\Rfc4122\\UuidInterface`. + + UuidV1 represents a :ref:`version 1, time-based UUID `. + In addition to providing the methods defined on the interface, this class + additionally provides the following methods. + + .. php:method:: getDateTime() + + :returns: (*\\DateTimeInterface*) A date object representing the timestamp associated with the UUID. diff --git a/docs/reference/uuid.rst b/docs/reference/uuid.rst index 5b3fc9e..cbee71e 100644 --- a/docs/reference/uuid.rst +++ b/docs/reference/uuid.rst @@ -12,6 +12,79 @@ the ramsey/uuid library. .. php:class:: Uuid + .. php:const:: UUID_TYPE_TIME + + :ref:`rfc4122.version1` UUID. + + .. php:const:: UUID_TYPE_DCE_SECURITY + + :ref:`rfc4122.version2` UUID. + + .. php:const:: UUID_TYPE_HASH_MD5 + + :ref:`rfc4122.version3` UUID. + + .. php:const:: UUID_TYPE_RANDOM + + :ref:`rfc4122.version4` UUID. + + .. php:const:: UUID_TYPE_HASH_SHA1 + + :ref:`rfc4122.version5` UUID. + + .. php:const:: UUID_TYPE_PEABODY + + :ref:`nonstandard.version6` UUID. + + .. php:const:: NAMESPACE_DNS + + The name string is a fully-qualified domain name. + + .. php:const:: NAMESPACE_URL + + The name string is a URL. + + .. php:const:: NAMESPACE_OID + + The name string is an `ISO object identifier (OID)`_. + + .. php:const:: NAMESPACE_X500 + + The name string is an `X.500`_ `DN`_ in `DER`_ or a text output format. + + .. php:const:: NIL + + The nil UUID is a special form of UUID that is specified to have all 128 + bits set to zero. + + .. php:const:: DCE_DOMAIN_PERSON + + DCE Security principal (person) domain. + + .. php:const:: DCE_DOMAIN_GROUP + + DCE Security group domain. + + .. php:const:: DCE_DOMAIN_ORG + + DCE Security organization domain. + + .. php:const:: RESERVED_NCS + + Variant identifier: reserved, NCS backward compatibility. + + .. php:const:: RFC_4122 + + Variant identifier: the UUID layout specified in RFC 4122. + + .. php:const:: RESERVED_MICROSOFT + + Variant identifier: reserved, Microsoft Corporation backward compatibility. + + .. php:const:: RESERVED_FUTURE + + Variant identifier: reserved for future definition. + .. php:staticmethod:: uuid1([$node[, $clockSeq]]) Generates a version 1, time-based UUID. See :ref:`rfc4122.version1`. @@ -24,7 +97,7 @@ the ramsey/uuid library. Generates a version 2, DCE Security UUID. See :ref:`rfc4122.version2`. - :param int $localDomain: The local domain to use (one of ``Uuid::DCE_DOMAIN_PERSON``, ``Uuid::DCE_DOMAIN_GROUP``, or ``Uuid::DCE_DOMAIN_ORG``) + :param int $localDomain: The local domain to use (one of :php:const:`Uuid::DCE_DOMAIN_PERSON`, :php:const:`Uuid::DCE_DOMAIN_GROUP`, or :php:const:`Uuid::DCE_DOMAIN_ORG`) :param Ramsey\\Uuid\\Type\\Integer|null $localIdentifier: A local identifier for the domain (defaults to system UID or GID for *person* or *group*) :param Ramsey\\Uuid\\Type\\Hexadecimal|null $node: An optional hexadecimal node to use :param int|null $clockSeq: An optional clock sequence to use @@ -84,7 +157,7 @@ the ramsey/uuid library. .. php:staticmethod:: fromDateTime($dateTime[, $node[, $clockSeq]]) - Creates a version 1 UUID instance from a ``DateTimeInterface`` instance. + Creates a version 1 UUID instance from a ``\DateTimeInterface`` instance. :param DateTimeInterface $dateTime: The date from which to create the UUID instance :param Ramsey\\Uuid\\Type\\Hexadecimal|null $node: An optional hexadecimal node to use @@ -98,18 +171,8 @@ the ramsey/uuid library. :param string $uuid: The string standard representation of a UUID :returns: True if the string UUID is valid, false otherwise - .. php:const:: NAMESPACE_DNS - 6ba7b810-9dad-11d1-80b4-00c04fd430c8 - - .. php:const:: NAMESPACE_URL - - 6ba7b811-9dad-11d1-80b4-00c04fd430c8 - - .. php:const:: NAMESPACE_OID - - 6ba7b812-9dad-11d1-80b4-00c04fd430c8 - - .. php:const:: NAMESPACE_X500 - - 6ba7b814-9dad-11d1-80b4-00c04fd430c8 +.. _ISO object identifier (OID): http://www.oid-info.com +.. _X.500: https://en.wikipedia.org/wiki/X.500 +.. _DN: https://en.wikipedia.org/wiki/Distinguished_Name +.. _DER: https://www.itu.int/rec/T-REC-X.690/ diff --git a/docs/rfc4122/version1.rst b/docs/rfc4122/version1.rst index 8d953a7..53c3058 100644 --- a/docs/rfc4122/version1.rst +++ b/docs/rfc4122/version1.rst @@ -76,7 +76,7 @@ check to see if it's a version 1 UUID by checking its instance type. } .. tip:: - Check out the :php:interface:`Ramsey\\Uuid\\Rfc4122\\UuidInterface` API + Check out the :php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV1` API documentation to learn more about what you can do with a ``UuidV1`` instance. diff --git a/docs/rfc4122/version3.rst b/docs/rfc4122/version3.rst index ef92446..8d3505b 100644 --- a/docs/rfc4122/version3.rst +++ b/docs/rfc4122/version3.rst @@ -4,75 +4,65 @@ Version 3: Name-based (MD5) =========================== -The first thing that comes to mind with most people think of a UUID is a -*random* identifier, but name-based UUIDs aren't random at all. In fact, they're -deterministic. For any given identical namespace and name, you will always -generate the same UUID. +.. attention:: -Name-based UUIDs are useful when you need an identifier that's based on -something's name and will always be the same for that name. + `RFC 4122`_ states, "If backward compatibility is not an issue, SHA-1 is + preferred." As a result, the use of :ref:`version 5 UUIDs + ` is preferred over version 3 UUIDs, unless you have a + specific use-case for version 3 UUIDs. -For example, let's say I want to create an identifier for a URL. I could use -a :ref:`version 1 ` or :ref:`version 4 ` -UUID to create an identifier for the URL, but what if I'm working with a -distributed system, and I want to ensure that every client in this system can -always generate the same identifier for any given URL in the system? +.. note:: -This is where a name-based UUID comes in handy. + To learn about name-based UUIDs, read the section :ref:`rfc4122.version5`. + Version 3 UUIDs behave exactly the same as :ref:`version 5 UUIDs + `. The only difference is the hashing algorithm used to + generate the UUID. -Name-based UUIDs combine a namespace with a name. This way, the UUIDs are unique -to the namespace they're created in. RFC 4122 defines some -:ref:`predefined namespaces `, one of which is -for URLs. + 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 +any given namespace and name will differ from version 5 UUIDs generated using +the same namespace and name. + +As an example, let's take a look at generating a version 3 UUID using the same +namespace and name used in ":ref:`rfc4122.version5.url-example`." .. code-block:: php - :caption: Generate a name-based UUID for a URL + :caption: Generate a version 3, name-based UUID for a URL + :name: rfc4122.version3.url-example use Ramsey\Uuid\Uuid; $uuid = Uuid::uuid3(Uuid::NAMESPACE_URL, 'https://www.php.net'); -The UUID generated will always be the same, as long as the namespace and name -are the same. +Even though the namespace and name are the same, the version 3 UUID generated +will always be ``3f703955-aaba-3e70-a3cb-baff6aa3b28f``. -.. hint:: - The version 3 UUID for "https://www.php.net" in the URL namespace will - always be ``3f703955-aaba-3e70-a3cb-baff6aa3b28f``. See for yourself. Run - the code above, and you'll see it always generates the same UUID. - - -.. _rfc4122.version3.custom-namespaces: - -Custom Namespaces -################# - -If you're working with name-based UUIDs for names that don't fit into any of -the :ref:`predefined namespaces `, or you don't -want to use any of the predefined namespaces, you can create your own namespace. - -The best way to do this is to generate a :ref:`version 1 ` or -:ref:`version 4 ` UUID and save this UUID as your namespace. +Likewise, we can use the custom namespace we created in +":ref:`rfc4122.version5.create-namespace`" to generate a version 3 UUID, but the +result will be different from the version 5 UUID with the same custom namespace +and name. .. code-block:: php - :caption: Generate a custom namespace UUID + :caption: Use a custom namespace to create version 3, name-based UUIDs + :name: rfc4122.version3.custom-example use Ramsey\Uuid\Uuid; - $uuid = Uuid::uuid4(); + const WIDGET_NAMESPACE = '4bdbe8ec-5cb5-11ea-bc55-0242ac130003'; - printf("My namespace UUID is %s\n", $uuid->toString()); - -This will generate a random UUID, which we'll store to a constant so we can -reuse it as our own custom namespace. - -.. code-block:: php - :caption: Use a custom namespace to create name-based UUIDs - - use Ramsey\Uuid\Uuid; - - const MY_NAMESPACE = '9a494836-ef67-4c63-a27b-15bc5a17e0ed'; - - $uuid = Uuid::uuid3(MY_NAMESPACE, 'widget/1234567890'); + $uuid = Uuid::uuid3(WIDGET_NAMESPACE, 'widget/1234567890'); With this custom namespace, the version 3 UUID for the name "widget/1234567890" -will always be ``f8e9b8cf-43a2-378b-9de0-aa714f6e989b``. +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. + + +.. _RFC 4122: https://tools.ietf.org/html/rfc4122 +.. _MD5: https://tools.ietf.org/html/rfc1321 diff --git a/docs/rfc4122/version5.rst b/docs/rfc4122/version5.rst index e916811..f568c59 100644 --- a/docs/rfc4122/version5.rst +++ b/docs/rfc4122/version5.rst @@ -3,3 +3,103 @@ ============================= Version 5: Name-based (SHA-1) ============================= + +.. caution:: + Since :ref:`version 3 ` 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 + store any sensitive information in a version 3 or version 5 UUID, since `MD5 + and SHA-1 are insecure and have known attacks demonstrated against them + `_. *Use these + types of UUIDs as identifiers only.* + +The first thing that comes to mind with most people think of a UUID is a +*random* identifier, but name-based UUIDs aren't random at all. In fact, they're +deterministic. For any given identical namespace and name, you will always +generate the same UUID. + +Name-based UUIDs are useful when you need an identifier that's based on +something's *name* --- think *identity* --- and will always be the same no +matter where or when it is created. + +For example, let's say I want to create an identifier for a URL. I could use +a :ref:`version 1 ` or :ref:`version 4 ` +UUID to create an identifier for the URL, but what if I'm working with a +distributed system, and I want to ensure that every client in this system can +always generate the same identifier for any given URL? + +This is where a name-based UUID comes in handy. + +Name-based UUIDs combine a namespace with a name. This way, the UUIDs are unique +to the namespace they're created in. RFC 4122 defines some +:ref:`predefined namespaces `, one of which is +for URLs. + +.. note:: + Version 5 UUIDs use `SHA-1`_ as the hashing algorithm for combining the + namespace and the name. + +.. code-block:: php + :caption: Generate a version 5, name-based UUID for a URL + :name: rfc4122.version5.url-example + + use Ramsey\Uuid\Uuid; + + $uuid = Uuid::uuid5(Uuid::NAMESPACE_URL, 'https://www.php.net'); + +The UUID generated will always be the same, as long as the namespace and name +are the same. The version 5 UUID for "https://www.php.net" in the URL namespace +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. + + +.. _rfc4122.version5.custom-namespaces: + +Custom Namespaces +################# + +If you're working with name-based UUIDs for names that don't fit into any of +the :ref:`predefined namespaces `, or you don't +want to use any of the predefined namespaces, you can create your own namespace. + +The best way to do this is to generate a :ref:`version 1 ` or +:ref:`version 4 ` UUID and save this UUID as your namespace. + +.. code-block:: php + :caption: Generate a custom namespace UUID + :name: rfc4122.version5.create-namespace + + use Ramsey\Uuid\Uuid; + + $uuid = Uuid::uuid1(); + + printf("My namespace UUID is %s\n", $uuid->toString()); + +This will generate a random UUID, which we'll store to a constant so we can +reuse it as our own custom namespace. + +.. code-block:: php + :caption: Use a custom namespace to create version 5, name-based UUIDs + :name: rfc4122.version5.custom-example + + use Ramsey\Uuid\Uuid; + + const WIDGET_NAMESPACE = '4bdbe8ec-5cb5-11ea-bc55-0242ac130003'; + + $uuid = Uuid::uuid5(WIDGET_NAMESPACE, 'widget/1234567890'); + +With this custom namespace, the version 5 UUID for the name "widget/1234567890" +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: http://dx.doi.org/10.6028/NIST.FIPS.180-4