Test
Test Documentation

UUIDs (aka GUIDs - Globally Unique Identifiers) are 128 bit long and are unique in time and space, either guaranteed or with a statistically insignificant likelihood of collisions (in the order of 2^-120). The IETF defines four versions of UUIDs that are either based on the MAC address and a timestamp, a hashed name, or randomly generated. To simplify Notifier message routing, we also add a custom type.

UUIDs with all bits 0 are called NULL UUIDs. Default constructed Uuid instances are NULL and the is_null method can be used to check whether a UUID is NULL.

IETF Format

The IETF UUIDs comprise of four components. We store them as a 16 byte array in the layout shown below. Note that in the case of the random or name-based UUIDs, the timestamp, sequence, and node address are either random or generated from a hash. Note: In addition to Notifier based UUIDs (see below), we allow to associate custom flags with a randomly generated UUID (create_random).

         7   6   5   4   3   2   1   0
       +—+—+—+—+—+—+—+—+
     0 |                               |

  • + 1 | |
  • time_low + 2 | |
  • + 3 | | +—+—+—+—+—+—+—+—+ 4 | |
  • time_mid + 5 | | +—+—+—+—+—+—+—+—+ 6 | |
  • time_high_and_version + 7 | | +—+—+—+—+—+—+—+—+ 8 | clock_seq_high_and_variant | +—+—+—+—+—+—+—+—+ 9 | clock_seq_low | +—+—+—+—+—+—+—+—+ 10 | |
  • + 11 | |
  • + 12 | |
  • node_address + 13 | |
  • + 14 | |
  • + 15 | | +—+—+—+—+—+—+—+—+
      Field               Size[bits]  Octet  Note
   -----------------------------------------------------------------------
   time_low               32          0-3    The low field of the
                                             timestamp in little-endian.
   time_mid               16          4-5    The middle field of the
                                             timestamp in little-endian.
   time_high              16          6-7    The high field of the timestamp
                                             multiplexed with the version number
                                             in little-endian representation.
   clock_seq_high_and_var 8           8      The high field of the clock sequence
   iant                                      multiplexed with the variant
   clock_seq_low          8           9      The low field of the clock sequence
   node                   48          10-15  The spatially unique node identifier
                                             (MAC address).
   

IMPORTANT: RFC4122 implies that time_low, time_mid, and time_high are big-endian (network byte order). However, Microsoft seems to assume they are little-endian when converting GUIDs to byte representations. Specifically, System.Guid.ToByteArray() clearly returns the fields in a little-endian format. Also, the Mono project explicitly emulates this behavior by performing endian conversions on big-endian platforms to ensure compatibility. Thus, to ensure compatibility with Windows (and to avoid confusion in the debugger and when interoperating with .NET, we stipulate that in the binary representation of the UUID, the timestamp is little-endian and the remaining fields are big-endian!

As the variant is always bit7=1 and bit6=0 (other than for legacy and some MSFT specific stuff, we assume the following simplified format:

         7   6   5   4   3   2   1   0
       +—+—+—+—+—+—+—+—+
     0 |                               |

  • + 1 | |
  • + 2 | |
  • + 3 | |
  • timestamp + 4 | |
  • + 5 | |
  • + 6 | | +—+—+—+—+ + 7 | version | | +—+—+—+—+—+—+—+—+ 8 | 1 | 0 | | +—+—+ sequence + 9 | | +—+—+—+—+—+—+—+—+ 10 | |
  • + 11 | |
  • + 12 | |
  • node_address + 13 | |
  • + 14 | |
  • + 15 | | +—+—+—+—+—+—+—+—+
      Field               Size[bits]  Octet  Note
   -----------------------------------------------------------------------
   timestamp              60          0-7    The timestamp (little-endian)
   version                4           7      UUID version in bit 4 to 7 of
                                             octet 7
   sequence               14          8-9    The clock sequence number as
                                             14 bit big-endian integer
   node                   48          10-15  The spatially unique node identifier.
   

Custom Data Field

This UUID class allows associating 8 bits of custom flags/data with a randomly generated or Notifier based UUIDs (note: custom data is not supported with sequential UUIDs). This can be very convenient to allow applications to type UUIDs it generates, but they have to beware that the custom flags cannot be modified once the UUID has been created.

As UUIDs are not strongly typed, applications have to beware that the UUID may not have been generated by it. It thus must be able to validate the UUID against a separate store before interpreting the custom flags (i.e. it should be sure that it actually generated the UUID).

IMPORTANT: Never make security relevant decisions based on the value of the custom flags unless the UUID has been validated on the application boundaries.

Random UUID Format

         7   6   5   4   3   2   1   0
       +—+—+—+—+—+—+—+—+
     0 |                               |

  • + 1 | |
  • + 2 | |
  • random (52 bits) + 3 | |
  • + 4 | |
  • + 5 | | +—+—+—+—+ + 6 | custom_low | | +—+—+—+—+—+—+—+—+ 7 | 0 | 1 | 0 | 0 | custom_high | +—+—+—+—+—+—+—+—+ 8 | 1 | 0 | | +—+—+ random (14 bits) + 9 | | +—+—+—+—+—+—+—+—+ 10 | |
  • + 11 | |
  • + 12 | |
  • random (48 bits) + 13 | |
  • + 14 | |
  • + 15 | | +—+—+—+—+—+—+—+—+
      Field               Size[bits]    Octet  Note
   -----------------------------------------------------------------------
   custom_low             4             6      Low 4 bits of the 8-bit custom field
                                               in bit 4 to 7 of octet 6
   custom_high            4             7      High 4 bits of the 8-bit custom field
                                               in bit 0 to 3 of octet 7
   

Note: The custom field is random unless explicitly specified by application when creating the UUID (create_random).

Name-based UUID Format

UUID is unique within a "namespace" for a particular sequence of bytes. This is achieved by hashing he namespace and data with MD-5. See RFC#4122 for details.

To avoid i3core being dependent on OpenSSL for crypto primitives, UUIDs of this type are created with i3crypto::create_name_based_uuid.

         7   6   5   4   3   2   1   0
       +—+—+—+—+—+—+—+—+
     0 |                               |

  • + 1 | |
  • + 2 | |
  • + 3 | |
  • MD-5(namespace|data) + 4 | |
  • + 5 | |
  • + 6 | | +—+—+—+—+ + 7 | 0 | 0 | 1 | 1 | | +—+—+—+—+ + 8 | 1 | 0 | | +—+—+ + 9 | |
  • + 10 | |
  • + 11 | |
  • + 12 | |
  • + 13 | |
  • + 14 | |
  • + 15 | | +—+—+—+—+—+—+—+—+
   Sequential UUID Format
   
         7   6   5   4   3   2   1   0
       +—+—+—+—+—+—+—+—+
     0 |                               |

  • + 1 | |
  • + 2 | |
  • + 3 | |
  • timestamp (56 bits) + 4 | |
  • + 5 | |
  • + 6 | | +—+—+—+—+—+—+—+—+ 7 | version | 0 | 0 | 0 | 0 | +—+—+—+—+—+—+—+—+ 8 | 1 | 0 | dbms | | +—+—+——– random1 + 9 | (12 bits) | +—+—+—+—+—+—+—+—+ 10 | |
  • + 11 | random2 & counterHi |
  • (32 bits) + 12 | |
  • + 13 | | +—+—+—+—+—+—+—+—+ 14 | |
  • counterLo (16 bits) + 15 | | +—+—+—+—+—+—+—+—+
      Field           Size[bits]  Octet  Note
   -----------------------------------------------------------------------
   timestamp          56          0-6    The timestamp (big-endian).
   version             4            7    The UUID version (eVersion_Sequential)
                                         in bits 4-7.
   zeroVal             4            7    A '0000' constant value in bits 0-3.
   variant             2            8    A '10' constant value in bits 7 and 6.
   dbms type           2            8    A '00' constant value in bits 5 and 4 by default for binary/oracle.
                                         i3db::create_sequential_with_db_collation may change it to 01 for sql server
   random1            12          8-9    A random number that only generated
                                         once (the first time
                                         create_sequential() is called).
   random2 &          32        10-13    A random number that is usually
   counterHi                             only generated once; however, it will
                                         be incremented (as a big-endian integer)
                                         if counterLo ever overflows.
   counterLo          16        14-15    The primary counter (big-endian).
   
   Legacy Interaction Id UUID Format
   
         7   6   5   4   3   2   1   0
       +—+—+—+—+—+—+—+—+
     0 |                               |

  • + 1 | |
  • + 2 | |
  • + 3 | |
  • random + 4 | |
  • + 5 | |
  • + 6 | | +—+—+—+—+ + 7 | 1 | 1 | 0 | 0 | | +—+—+—+—+ + 8 | 1 | 0 | | +—+—+ + 9 | | +—+—+—+—+—+—+—+—+ 10 | reserved (0) | +—+—+—+—+—+—+—+—+ 11 | digit9 | digit8 | +—+—+—+—+—+—+—+—+ 12 | digit7 | digit6 | +—+—+—+—+—+—+—+—+ 13 | digit5 | digit4 | +—+—+—+—+—+—+—+—+ 14 | digit3 | digit2 | +—+—+—+—+—+—+—+—+ 15 | digit1 | digit0 | +—+—+—+—+—+—+—+—+
      Field           Size[bits]  Octet  Note
   -----------------------------------------------------------------------
   random             74          0-9    74 random bits.  All-zeroes if unresolved ID.
   flags              8           10     Custom flags for use by issuer of legacy UUID.
                                         Zero by default to have leading zeroes in interaction ID.
   digit9             4           11     The binary representation of the most significant
                                         decimal digit of the ten digit interaction ID.
   digit8             4           11     The binary representation of the second most significant
                                         decimal digit of the ten digit interaction ID.
   ...
   digit0             4           15     The binary representation of the least significant
                                         decimal digit of the ten digit interaction ID.
   
   Note: When converted to a string representation using the Uuid::as_string() method, this
   format will result in the 12 character segment at the end of the UUID representing
   the decimal interaction ID for easy readability in logs.  A decimal interaction ID of
   1234567890 will thus have a string representation of:
   
   xxxxxxxx-xxxx-cxxx-xxxx-001234567890
   
   By default, there will be two leading zero digits before the digits of the interaction ID.
   The issuer of the UUID has the option to use the octet of these leading two characters as
   flags (the nibbles in the octet can of course use the full hex value range).
   Components that need to communicate a legacy interaction to the issuer of the UUID
   can create an "unresolved" UUID by setting the 'random' field to all zeroes.
   Notifier Format
   To simplify message routing and handling of instance identifiers
   in Notifier, we also introduce Notifier based UUIDs.  Not only do
   they guarantee uniqueness within the context of ION, but they also
   encode the Notifier server and local connection.  Notifier instance
   identifiers represent Notifier based UUIDs and thus allow a Notifier
   server to directly route messages sent to instances without having
   to maintain maps or server-side registrations.
   
         7   6   5   4   3   2   1   0
       +—+—+—+—+—+—+—+—+
     0 |                               |

  • + 1 | |
  • + 2 | |
  • instance_sequence + 3 | |
  • + 4 | |
  • + 5 | | +—+—+—+—+ + 6 | custom_low | | +—+—+—+—+—+—+—+—+ 7 | 1 | 1 | 1 | 0 | custom_high | +—+—+—+—+—+—+—+—+ 8 | 1 | 0 | | +—+—+ connection_id + 9 | | +—+—+—+—+—+—+—+—+ 10 | |
  • + 11 | |
  • + 12 | |
  • node_address + 13 | |
  • + 14 | |
  • + 15 | | +—+—+—+—+—+—+—+—+

    |

      Field               Size[bits]    Octet  Note
   -----------------------------------------------------------------------
   instance_sequence      52            0-6    Instance sequence number (unique for
                                               each connection_id/node_address pair.
                                               See note below for details.
   custom_low             4             6      Low 4 bits of the 8-bit custom field
                                               in bit 4 to 7 of octet 6
   custom_high            4             7      High 4 bits of the 8-bit custom field
                                               in bit 0 to 3 of octet 7
   connection_id          14            8-9    Local connection identifier as 14-bit
                                               big-endian integer
   node_address           48            10-15  The spatially unique node identifier
                                               (MAC address as Notifier ID).
   
   Note: To ensure temporal uniqueness of a Notifier UUID created for a particular
   node_address/connection_id pair, a created instance_sequence
   value must be greater than the number of microseconds since 2000-01-01T00:00:00Z
   at the time when Notifier associated the connection_id with that node_address.
   It also must be less than the number of microsoeconds since 2000-01-01T00:00:00Z
   at the time when the UUID is generated.
   
Author:
felixw