DEV Community

Anh Trần Tuấn
Anh Trần Tuấn

Posted on • Originally published at tuanh.net on

Facts About UUID Versions: Which Version Should You Use and Why?

1. What is a UUID?

Image

UUID stands for Universally Unique Identifier. It is a 128-bit number used to uniquely identify information in computer systems. UUIDs are widely used in databases, distributed systems, and anywhere unique identifiers are needed without significant risk of duplication. A typical UUID looks like this:

123e4567-e89b-12d3-a456-426614174000
Enter fullscreen mode Exit fullscreen mode

1.1 The Purpose of UUIDs

UUIDs serve as a practical solution for generating unique identifiers without a central coordinating authority. This is particularly useful in distributed environments, such as cloud applications, microservices, and databases, where it is impractical or impossible to maintain a central registry of unique keys.

1.2 Structure of a UUID

A UUID is represented as a 32-character hexadecimal string, split into five groups separated by hyphens. Its structure consists of different fields, such as time-based fields, version numbers, and variant identifiers, depending on the UUID version.

1.3 Benefits of Using UUIDs

UUIDs provide several benefits:

  • Global Uniqueness : No two UUIDs are the same, ensuring the integrity of data.
  • Decentralized Generation : UUIDs can be generated in multiple systems without the risk of collision.
  • Compatibility : UUIDs are supported in most programming languages and database systems.

1.4 Drawbacks of UUIDs

While UUIDs are incredibly useful, they come with certain drawbacks:

  • Size : UUIDs are 128 bits (16 bytes), making them larger than standard numeric IDs.
  • Performance Impact : In some cases, UUIDs may impact database indexing and lookup performance due to their size.

2. An Overview of UUID Versions

UUIDs come in several versions, each serving different purposes. Understanding these versions will help you choose the one that best fits your use case.

2.1 UUID Version 1 (Time-Based)

Version 1 UUIDs are time-based UUIDs that incorporate the current timestamp and the MAC address of the machine generating the UUID.

A UUID Version 1 is structured as follows:

  • First 32 bits (8 hex digits): Represent the low part of the timestamp.
  • Next 16 bits (4 hex digits): Represent the mid part of the timestamp.
  • Next 4 bits (1 hex digit) + Version (4 bits): Represent the high part of the timestamp and the UUID version (always 1 for Version 1).
  • Next 2 hex digits (6 bits variant + 8 bits clock sequence): Represent the variant (RFC 4122) and clock sequence.
  • Last 48 bits (12 hex digits): Represent the node (MAC address of the host).

Image

Explanation

time_low (8 hex digits, 32 bits): f47ac10b Represents the lower 32 bits of the timestamp.

time_mid (4 hex digits, 16 bits): 58cc Represents the middle 16 bits of the timestamp.

time_hi_version (4 hex digits, 16 bits): 11f1 Represents the high 12 bits of the timestamp and 4 bits for the version (1 for Version 1).

clock_seq_variant (4 hex digits, 16 bits): a8a0 Represents the variant (a in hexadecimal for RFC 4122 standard) and clock sequence (8a0).

node (12 hex digits, 48 bits): 08002b2b0000 Represents the 48-bit node identifier, usually the MAC address.

Strengths:

  • Ensures uniqueness across different systems due to the use of MAC addresses.
  • Ideal for use cases where the order of creation is important.

Weaknesses

  • The inclusion of the MAC address can lead to privacy concerns.
  • Predictable, as the UUIDs are time-based and can be guessed if the time and MAC address are known.

2.2 UUID Version 2 (DCE Security)

Version 2 is similar to Version 1 but adds security by incorporating a user's POSIX UID or GID.

UUID Version 2 follows a specific structure that includes time-based fields, a version number, a local domain identifier, and a node identifier (usually the MAC address). Here’s a breakdown:

Time-based Fields (60 bits total):

  • First 32 bits (8 hex digits): Lower part of the timestamp.
  • Next 16 bits (4 hex digits): Middle part of the timestamp.

UUID Version (4 bits): Indicates the UUID version, set to 2 for Version 2.

Local Domain and Local ID (16 bits total):

  • Local Domain (8 bits): Specifies the type of local domain (e.g., POSIX UID/GID).
  • Local ID (8 bits): Identifier for the local domain (e.g., user or group ID).

Clock Sequence (14 bits total):

  • Next 6 bits (1.5 hex digits): Variant according to RFC 4122.
  • Remaining 8 bits (2 hex digits): Clock sequence, for uniqueness when generating UUIDs rapidly.

Node (48 bits total): Last 12 hex digits: Node identifier, typically the MAC address of the device.

f81d4fae-7dec-2e4a-9a4f-020b56000000
Enter fullscreen mode Exit fullscreen mode

Image

Explanation of Each Part

Timestamp (32 bits): This represents the first 32 bits (8 hex digits) of the UUID and is used for time-based uniqueness.

Domain (16 bits): This field (4 hex digits) stores domain-specific information like POSIX UID/GID.

Version (4 bits): This value is fixed to 2 for Version 2 UUIDs.

Variant (6 bits): Specifies the variant of the UUID, which follows the RFC 4122 standard.

Clock Sequence (8 bits): This is used to help avoid duplicates in cases of rapid UUID generation.

Node (48 bits): The final 12 hex digits typically represent the MAC address of the machine where the UUID is generated.

Strengths:

  • Adds an extra layer of security by incorporating user-specific data.

  • Rarely used and not widely supported in programming libraries.

  • Limited use cases and practicality.

2.3 UUID Version 3 (Name-Based, MD5 Hash)

Version 3 UUIDs use MD5 hashing and a namespace to generate a UUID based on a name (e.g., URL, FQDN).

A UUID Version 3 is a name-based identifier that is generated by hashing a namespace identifier and a name using the MD5 hashing algorithm. The UUID Version 3 is deterministic, meaning it will always produce the same UUID for the same namespace and name.

A UUID v3 is structured as follows:

  • Namespace : A UUID that identifies a namespace for the name. This is typically a UUID that serves as a prefix.
  • Name : A string that, together with the namespace, is hashed to produce the UUID.
  • MD5 Hash : The MD5 hash of the namespace and name combined to produce a 128-bit value.
  • UUID Format : The UUID is formatted into a 36-character string, including hyphens, and divided into five segments.

Example of UUID v3

Let's say we want to generate a UUID v3 with the following parameters:

  • Namespace UUID: 123e4567-e89b-12d3-a456-426614174000
  • Name: example.com

Assuming the result of the MD5 hash is 1b4e28ba-2fa1-11d2-883f-0016d3cca427 , the UUID v3 for the namespace 123e4567-e89b-12d3-a456-426614174000 and name example.com would be:

1b4e28ba-2fa1-11d2-883f-0016d3cca427
Enter fullscreen mode Exit fullscreen mode

The UUID v3 consists of 5 components separated by hyphens. Here's how it is structured:

xxxxxxxx-xxxx-3xxx-yxxx-xxxxxxxxxxxx
Enter fullscreen mode Exit fullscreen mode
  • xxxxxxxx-xxxx : Time-low and Time-mid fields.
  • 3xxx : The version field, where "3" indicates UUID v3.
  • yxxx : The variant field, which indicates the layout of the UUID.
  • xxxxxxxxxxxx : The remaining fields.

For the UUID 1b4e28ba-2fa1-11d2-883f-0016d3cca427 , the components are:

  • Time-low : 1b4e28ba
  • Time-mid : 2fa1
  • Version : 1 (indicating UUID v3)
  • Time-high-and-version : 1d2 (combined with version)
  • Variant : 8
  • Clock-seq : 83f
  • Node : 0016d3cca427

Here's a diagram illustrating these components:

+-----------+-----------+-----+-----+-----------------+
| Time-low | Time-mid | Ver | Var | Clock-seq & Node|
| (8 hex) | (4 hex) | 3 | 8 | (12 hex) |
+-----------+-----------+-----+-----+-----------------+
Enter fullscreen mode Exit fullscreen mode

Strengths:

  • Deterministic: The same input will always generate the same UUID.
  • Useful for creating UUIDs from names in distributed systems.

Weaknesses:

  • Vulnerable to MD5 hash collisions and not cryptographically secure.
  • Less random and unique than other versions.

2.4 UUID Version 4 (Random-Based)

UUID v4 (Universally Unique Identifier version 4) is a type of UUID that is generated randomly. Unlike UUID v3, which is based on a namespace and name, UUID v4 is created using random or pseudo-random numbers. This means that UUID v4 does not have any intrinsic meaning or pattern; it is designed to be unique simply due to its random nature.

A UUID v4 is structured as follows:

  • Random Bits : The UUID is generated using random bits.
  • Version : The version field indicates that this is a UUID v4.
  • Variant : The variant field specifies the layout of the UUID.

The UUID v4 is formatted into a 36-character string with 32 hexadecimal digits and 4 hyphens, divided into five segments:

xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
Enter fullscreen mode Exit fullscreen mode
  • xxxxxxxx : Time-low field (8 hex digits).
  • xxxx : Time-mid field (4 hex digits).
  • 4xxx : Time-high-and-version field, where "4" indicates UUID v4 (4 hex digits).
  • yxxx : Clock-seq-and-variant field, where "y" indicates the variant (4 hex digits).
  • xxxxxxxxxxxx : Node field (12 hex digits).

Here's an example of a UUID v4:

f47ac10b-58cc-4fdc-9a1e-3d8a1b0d0f9e
Enter fullscreen mode Exit fullscreen mode

For the UUID f47ac10b-58cc-4fdc-9a1e-3d8a1b0d0f9e , the components are:

  • Time-low : f47ac10b
  • Time-mid : 58cc
  • Version : 4 (indicating UUID v4)
  • Clock-seq-and-variant : 9a1e (where 9 indicates the variant)
  • Node : 3d8a1b0d0f9e

Here's a diagram illustrating these components:

+-----------+-----------+-----+-----+-----------------+
| Time-low | Time-mid | Ver | Var | Node |
| (8 hex) | (4 hex) | 4 | y | (12 hex) |
+-----------+-----------+-----+-----+-----------------+
Enter fullscreen mode Exit fullscreen mode

Strengths:

  • Simple and widely used due to its randomness.
  • Highly unpredictable and secure.

Weaknesses:

  • No order or predictability, making them unsuitable for certain use cases requiring sorted data.

2.5 UUID Version 5 (Name-Based, SHA-1 Hash)

UUID v5 (Universally Unique Identifier version 5) is a type of UUID that is generated using a hashing algorithm, specifically SHA-1, similar to UUID v3. It is used to generate a UUID based on a namespace and a name. The key difference between UUID v5 and UUID v3 is the hashing algorithm: UUID v5 uses SHA-1 instead of MD5, which provides a different hash output.

Structure of UUID v5

A UUID v5 is structured as follows:

  • Namespace : A UUID that identifies a namespace for the name. This is typically a UUID that serves as a prefix.
  • Name : A string that, together with the namespace, is hashed to produce the UUID.
  • SHA-1 Hash : The SHA-1 hash of the namespace and name combined to produce a 128-bit value.
  • UUID Format : The UUID is formatted into a 36-character string, including hyphens, and divided into five segments.

UUID v5 Format

The UUID v5 is formatted into a 36-character string with 32 hexadecimal digits and 4 hyphens, divided into five segments:

xxxxxxxx-xxxx-5xxx-yxxx-xxxxxxxxxxxx
Enter fullscreen mode Exit fullscreen mode
  • xxxxxxxx : Time-low field (8 hex digits).
  • xxxx : Time-mid field (4 hex digits).
  • 5xxx : Time-high-and-version field, where "5" indicates UUID v5 (4 hex digits).
  • yxxx : Clock-seq-and-variant field, where "y" indicates the variant (4 hex digits).
  • xxxxxxxxxxxx : Node field (12 hex digits).

Example of UUID v5

Let's say we want to generate a UUID v5 with the following parameters:

  • Namespace UUID : 123e4567-e89b-12d3-a456-426614174000
  • Name : example.com

Assuming the result of the SHA-1 hash is f47ac10b-58cc-5fdc-9a1e-3d8a1b0d0f9e , the UUID v5 for the namespace 123e4567-e89b-12d3-a456-426614174000 and name example.com would be:

f47ac10b-58cc-5fdc-9a1e-3d8a1b0d0f9e
Enter fullscreen mode Exit fullscreen mode

For the UUID f47ac10b-58cc-5fdc-9a1e-3d8a1b0d0f9e , the components are:

  • Time-low : f47ac10b
  • Time-mid : 58cc
  • Version : 5 (indicating UUID v5)
  • Clock-seq-and-variant : 9a1e (where 9 indicates the variant)
  • Node : 3d8a1b0d0f9e

Here's a diagram illustrating these components:

+-----------+-----------+-----+-----+-----------------+
| Time-low | Time-mid | Ver | Var | Node |
| (8 hex) | (4 hex) | 5 | y | (12 hex) |
+-----------+-----------+-----+-----+-----------------+
Enter fullscreen mode Exit fullscreen mode

Strengths:

  • Deterministic with better security than Version 3.
  • Suitable for scenarios where reproducibility is essential.

Weaknesses:

  • Vulnerable to SHA-1 collisions and not cryptographically secure.

2.6 UUID Version 6, 7, and 8 (Experimental)

UUID v6 (Universally Unique Identifier version 6) is a proposed version of UUIDs that aims to improve upon the time-based UUIDs (such as UUID v1) by offering better ordering and increased compatibility with certain use cases. UUID v6, v7, v8 is not yet officially standardized, but it has been proposed as a way to provide a time-based UUID with some improvements.

Structure of UUID v6

UUID v6 is designed to be a time-based UUID with the following structure:

  • Timestamp : Represents the time when the UUID was generated. It includes the date and time components.
  • Clock Sequence : A value used to ensure uniqueness in case of clock rollbacks or UUID collisions.
  • Node : Usually a unique identifier for the machine or process generating the UUID.

UUID v6 Format

The UUID v6 is formatted into a 36-character string with 32 hexadecimal digits and 4 hyphens, divided into five segments:

xxxxxxxx-xxxx-6xxx-yxxx-xxxxxxxxxxxx
Enter fullscreen mode Exit fullscreen mode
  • xxxxxxxx : Timestamp-low field (8 hex digits).
  • xxxx : Timestamp-mid field (4 hex digits).
  • 6xxx : Timestamp-high-and-version field, where "6" indicates UUID v6 (4 hex digits).
  • yxxx : Clock-seq-and-variant field, where "y" indicates the variant (4 hex digits).
  • xxxxxxxxxxxx : Node field (12 hex digits).

Example of UUID v6

Suppose we generate a UUID v6 with a timestamp and other components. For example:

0a1b2c3d-4e5f-6123-9abc-def012345678
Enter fullscreen mode Exit fullscreen mode

Components Breakdown

  • Timestamp-low : 0a1b2c3d
  • Timestamp-mid : 4e5f
  • Version : 6 (indicating UUID v6)
  • Clock-seq-and-variant : 9abc
  • Node : def012345678

The UUID v6 consists of 5 components separated by hyphens. Here's how it is structured:

xxxxxxxx-xxxx-6xxx-yxxx-xxxxxxxxxxxx
Enter fullscreen mode Exit fullscreen mode

Strengths:

  • Designed to optimize both security and performance.
  • Incorporates lessons learned from earlier versions.

Weaknesses:

  • Experimental and not widely adopted yet.

3. Which UUID Version Should You Use?

3.1 Popularity and Use Cases

  • Version 4 : Most popular due to its simplicity and randomness.
  • Version 1 : Useful for time-based ordering but comes with privacy concerns.
  • Version 5 : Good for name-based UUIDs where determinism is needed.

3.2 Recommended Version

For most applications, UUID Version 4 is the best choice due to its simplicity, randomness, and wide support in various programming environments. However, if you need deterministic UUIDs or need to encode metadata, you may opt for Version 5.

4. Conclusion

Choosing the right UUID version depends on your specific needs:

  • For random identifiers, go with Version 4.
  • For deterministic identifiers, use Version 5.
  • For time-based uniqueness, consider Version 1 , but be aware of privacy implications.

Understanding UUID versions is crucial for designing reliable systems. Have questions about UUIDs or which version to choose for your project? Feel free to leave a comment below!

Read posts more at : Facts About UUID Versions: Which Version Should You Use and Why?

Top comments (0)