guid.rst 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. .. _nonstandard.guid:
  2. ===================================
  3. Globally Unique Identifiers (GUIDs)
  4. ===================================
  5. .. tip::
  6. Using these techniques to work with GUIDs is useful if you're working with
  7. identifiers that have been stored in GUID byte order. For example, this is
  8. the case if working with the ``UNIQUEIDENTIFIER`` data type in Microsoft SQL
  9. Server. This is a GUID, stored as a 16-byte binary string. If working
  10. directly with the bytes, you may use the GUID functionality in ramsey/uuid
  11. to properly handle this data type.
  12. According to the Windows Dev Center article on `GUID structure`_, "GUIDs are the
  13. Microsoft implementation of the distributed computing environment (DCE)
  14. universally unique identifier." For all intents and purposes, a GUID string
  15. representation is identical to that of an `RFC 4122`_ UUID. For historical
  16. reasons, *the byte order is not*.
  17. The `.NET Framework documentation`_ explains:
  18. Note that the order of bytes in the returned byte array is different from
  19. the string representation of a Guid value. The order of the beginning
  20. four-byte group and the next two two-byte groups is reversed, whereas the
  21. order of the last two-byte group and the closing six-byte group is the same.
  22. This is best explained by example.
  23. .. code-block:: php
  24. :caption: Decoding a GUID from byte representation
  25. :name: nonstandard.guid.decode-bytes-example
  26. use Ramsey\Uuid\FeatureSet;
  27. use Ramsey\Uuid\UuidFactory;
  28. // The bytes of a GUID previously stored in some datastore.
  29. $guidBytes = hex2bin('0eab93fc9ec9584b975e9c5e68c53624');
  30. $useGuids = true;
  31. $featureSet = new FeatureSet($useGuids);
  32. $factory = new UuidFactory($featureSet);
  33. $guid = $factory->fromBytes($guidBytes);
  34. printf(
  35. "Class: %s\nGUID: %s\nVersion: %d\nBytes: %s\n",
  36. get_class($guid),
  37. $guid->toString(),
  38. $guid->getFields()->getVersion(),
  39. bin2hex($guid->getBytes())
  40. );
  41. This transforms the bytes of a GUID, as represented by ``$guidBytes``, into a
  42. :php:class:`Ramsey\\Uuid\\Guid\\Guid` instance and prints out some details about
  43. it. It looks something like this:
  44. .. code-block:: text
  45. Class: Ramsey\Uuid\Guid\Guid
  46. GUID: fc93ab0e-c99e-4b58-975e-9c5e68c53624
  47. Version: 4
  48. Bytes: 0eab93fc9ec9584b975e9c5e68c53624
  49. Note the difference between the string GUID and the bytes. The bytes are
  50. arranged like this:
  51. .. code-block:: text
  52. 0e ab 93 fc 9e c9 58 4b 97 5e 9c 5e 68 c5 36 24
  53. In an `RFC 4122`_ UUID, the bytes are stored in the same order as you see
  54. presented in the string representation. This is often called *network byte
  55. order*, or *big-endian* order. In a GUID, the order of the bytes are reversed
  56. in each grouping for the first 64 bits and stored in *little-endian* order. The
  57. remaining 64 bits are stored in network byte order. See `Endianness
  58. <#nonstandard-guid-endianness>`_ to learn more.
  59. .. caution::
  60. The bytes themselves do not indicate their order. If you decode GUID bytes
  61. as a UUID or UUID bytes as a GUID, you will get the wrong values. However,
  62. you can always create a GUID or UUID from the same string value; the bytes
  63. for each will be in a different order, even though the string is the same.
  64. The key is to know ahead of time in what order the bytes are stored. Then,
  65. you will be able to decode them using the correct approach.
  66. Converting GUIDs to UUIDs
  67. #########################
  68. Continuing from the example, :ref:`nonstandard.guid.decode-bytes-example`, we
  69. can take the GUID string representation and convert it into a standard UUID.
  70. .. code-block:: php
  71. :caption: Convert a GUID to a UUID
  72. :name: nonstandard.guid.convert-example
  73. $uuid = Uuid::fromString($guid->toString());
  74. printf(
  75. "Class: %s\nUUID: %s\nVersion: %d\nBytes: %s\n",
  76. get_class($uuid),
  77. $uuid->toString(),
  78. $uuid->getFields()->getVersion(),
  79. bin2hex($uuid->getBytes())
  80. );
  81. Because the GUID was a version 4, random UUID, this creates an instance of
  82. :php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV4` from the GUID string and prints out a
  83. few details about it. It looks something like this:
  84. .. code-block:: text
  85. Class: Ramsey\Uuid\Rfc4122\UuidV4
  86. UUID: fc93ab0e-c99e-4b58-975e-9c5e68c53624
  87. Version: 4
  88. Bytes: fc93ab0ec99e4b58975e9c5e68c53624
  89. Note how the UUID string is identical to the GUID string. However, the byte
  90. order is different, since they are in big-endian order. The bytes are now
  91. arranged like this:
  92. .. code-block:: text
  93. fc 93 ab 0e c9 9e 4b 58 97 5e 9c 5e 68 c5 36 24
  94. .. admonition:: Endianness
  95. :name: nonstandard.guid.endianness
  96. Big-endian and little-endian refer to the ordering of bytes in a multi-byte
  97. number. Big-endian order places the most significant byte first, followed by
  98. the other bytes in descending order. Little-endian order places the least
  99. significant byte first, followed by the other bytes in ascending order.
  100. Take the hexadecimal number ``0x1234``, for example. In big-endian order,
  101. the bytes are stored as ``12 34``, and in little-endian order, they are
  102. stored as ``34 12``. In either case, the number is still ``0x1234``.
  103. Networking protocols usually use big-endian ordering, while computer
  104. processor architectures often use little-endian ordering.
  105. The terms originated in Jonathan Swift's *Gulliver's Travels*, where the
  106. Lilliputians argue over which end of a hard-boiled egg is the best end to
  107. crack.
  108. .. _GUID structure: https://docs.microsoft.com/en-us/windows/win32/api/guiddef/ns-guiddef-guid#remarks
  109. .. _RFC 4122: https://tools.ietf.org/html/rfc4122
  110. .. _.NET Framework documentation: https://docs.microsoft.com/en-us/dotnet/api/system.guid.tobytearray#remarks