version5.rst 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. .. _rfc4122.version5:
  2. =============================
  3. Version 5: Name-based (SHA-1)
  4. =============================
  5. .. danger::
  6. Since :ref:`version 3 <rfc4122.version3>` and version 5 UUIDs essentially
  7. use a *salt* (the namespace) to hash data, it may be tempting to use them to
  8. hash passwords. **DO NOT do this under any circumstances!** You should not
  9. store any sensitive information in a version 3 or version 5 UUID, since `MD5
  10. and SHA-1 are insecure and have known attacks demonstrated against them
  11. <https://en.wikipedia.org/wiki/Hash_function_security_summary>`_. *Use these
  12. types of UUIDs as identifiers only.*
  13. The first thing that comes to mind with most people think of a UUID is a
  14. *random* identifier, but name-based UUIDs aren't random at all. In fact, they're
  15. deterministic. For any given identical namespace and name, you will always
  16. generate the same UUID.
  17. Name-based UUIDs are useful when you need an identifier that's based on
  18. something's *name* --- think *identity* --- and will always be the same no
  19. matter where or when it is created.
  20. For example, let's say I want to create an identifier for a URL. I could use
  21. a :ref:`version 1 <rfc4122.version1>` or :ref:`version 4 <rfc4122.version4>`
  22. UUID to create an identifier for the URL, but what if I'm working with a
  23. distributed system, and I want to ensure that every client in this system can
  24. always generate the same identifier for any given URL?
  25. This is where a name-based UUID comes in handy.
  26. Name-based UUIDs combine a namespace with a name. This way, the UUIDs are unique
  27. to the namespace they're created in. `RFC 4122`_ defines some
  28. :ref:`predefined namespaces <reference.name-based-namespaces>`, one of which is
  29. for URLs.
  30. .. note::
  31. Version 5 UUIDs use `SHA-1`_ as the hashing algorithm for combining the
  32. namespace and the name.
  33. .. code-block:: php
  34. :caption: Generate a version 5, name-based UUID for a URL
  35. :name: rfc4122.version5.url-example
  36. use Ramsey\Uuid\Uuid;
  37. $uuid = Uuid::uuid5(Uuid::NAMESPACE_URL, 'https://www.php.net');
  38. The UUID generated will always be the same, as long as the namespace and name
  39. are the same. The version 5 UUID for "https://www.php.net" in the URL namespace
  40. will always be ``a8f6ae40-d8a7-58f0-be05-a22f94eca9ec``. See for yourself. Run
  41. the code above, and you'll see it always generates the same UUID.
  42. .. tip::
  43. Version 5 UUIDs generated in ramsey/uuid are instances of UuidV5. Check out
  44. the :php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV5` API documentation to learn
  45. more about what you can do with a UuidV5 instance.
  46. .. _rfc4122.version5.custom-namespaces:
  47. Custom Namespaces
  48. #################
  49. If you're working with name-based UUIDs for names that don't fit into any of
  50. the :ref:`predefined namespaces <reference.name-based-namespaces>`, or you don't
  51. want to use any of the predefined namespaces, you can create your own namespace.
  52. The best way to do this is to generate a :ref:`version 1 <rfc4122.version1>` or
  53. :ref:`version 4 <rfc4122.version4>` UUID and save this UUID as your namespace.
  54. .. code-block:: php
  55. :caption: Generate a custom namespace UUID
  56. :name: rfc4122.version5.create-namespace
  57. use Ramsey\Uuid\Uuid;
  58. $uuid = Uuid::uuid1();
  59. printf("My namespace UUID is %s\n", $uuid->toString());
  60. This will generate a version 1, Gregorian time UUID, which we'll store to a
  61. constant so we can reuse it as our own custom namespace.
  62. .. code-block:: php
  63. :caption: Use a custom namespace to create version 5, name-based UUIDs
  64. :name: rfc4122.version5.custom-example
  65. use Ramsey\Uuid\Uuid;
  66. const WIDGET_NAMESPACE = '4bdbe8ec-5cb5-11ea-bc55-0242ac130003';
  67. $uuid = Uuid::uuid5(WIDGET_NAMESPACE, 'widget/1234567890');
  68. With this custom namespace, the version 5 UUID for the name "widget/1234567890"
  69. will always be ``a35477ae-bfb1-5f2e-b5a4-4711594d855f``.
  70. We can publish this namespace, allowing others to use it to generate identifiers
  71. for widgets. When two or more systems try to reference the same widget, they'll
  72. end up generating the same identifier for it, which is exactly what we want.
  73. .. _RFC 4122: https://tools.ietf.org/html/rfc4122
  74. .. _SHA-1: https://en.wikipedia.org/wiki/SHA-1