UUID - GUID Versions and Variants - Generating UUID Examples

1- Introduction

In our previous article, we gave more basic information about the UUID. We also talked about the advantages and disadvantages of the UUIDs.

In this article, we will cover the UUID versions and the variant values. Then generate the UUID values for some UUID versions.

2- UUID Format

UUID format is about a character string that consists of 32 hexadecimal characters, separated by four dashes, in the format of 8-4-4-4-12, with five groups and a total of 36 characters.

3- Understanding UUID Version and Variant Values

It can be easily understood which version and which variant value from the generated UUID.

xxxxxxxx-xxxx-Xxxx-Yxxx-xxxxxxxxxxxx

3.1 - X (Version)
  • Specifies the UUID "version"
  • The hexadecimal value directly displays the version value.
3.2 Y (Variant)
  • Specifies the UUID "Variant" value.
  • To understand the variant value, it is necessary to look at the range that the hexadecimal value corresponds to. (These ranges are shown in the table below)
Binary Hex Digit Varyant
0xxx 0 - 7 Variant 0 (1 bit) - Reserved NCS (Network Computing System) backward compatibility.
10xx 8 - b Variant 1 (2 bit) - RFC 4122/DCE 1.1 UUIDs
110x c - d Variant 2 (3 bit) - Reserved, Microsoft Corporation backward compatibility
111x e - f Variant 3 - Reserved for future definition.

Let's look at a few UUID Examples and Let's figure out the Version and Variant values;

2f45493b-9360-11ec-acae-4f4fe1145b2c —> Version 1, Variant 1
f385a913-2af7-4020-94d3-d4579f47d9e3 —> Version 4, Variant 1
3aea5a63-f50b-5bf2-93b8-7e99df390f4d —> Version 5, Variant 1

4 - UUID Versions

4.1 - Version 1 UUID

  • Version-1 is based on the current available time (timestamp) value and MAC address by the computer that generated the UUID.
  • The corresponding date initial value is based on 100 nanoseconds from October 15, 1582.
  • If the mac address (node) and timestamp are known, it will be easy to guess and reproduce.
  • UUID values produced on two different machines cannot be duplicated due to the Mac address (node) value.

4.1.1 Generating Version 1 UUID

PostgreDB

  • SELECT uuid_generate_v1();

Linux Terminal

  • uuidgen -t

Let's run this script one after the other with the command;

Generated UUID values will be;

"2fce3ee4-95d3-11ec-9848-4f4fe1145b2c"
"30a7b624-95d3-11ec-9848-4f4fe1145b2c"

All hexadecimal values ​​are the same except for the first 8 hexadecimal values. The last 12 hexadecimal values reflect the node value (the mac address value).

When we take the computer's time forward by 2 and generate it again;
SELECT uuid_generate_v1(); or uuidgen -t

"86cda5ca-9765-11ec-9848-4f4fe1145b2c" will be generated.

Let's move computer time forward a few years and get it running again;
SELECT uuid_generate_v1(); or uuidgen -t

"4b5bd632-70b2-11f4-9848-4f4fe1145b2c"

As we can see, the hexadecimal values are changing. The following table can be examined for the formation of the UUID order here.

Note: In version 1, the last 12 hexadecimal values of the UUID value are generated from the node value, ie the mac address by default. This value can be found by decoding.
As a solution to this, random node values can be preferred instead of mac address in version 1 implementations.
Name Bytes - Length Hex Digits - Length Bits - Length Contents
time_low 4 8 32 the low 32 bits of the time
time_mid 2 4 16 the middle 16 bits of the time
time_hi_and_version 2 4 16 (t4-bit "version" in the most significant bits, followed by the high 12 bits of the time
clock_seq_hi_and_res clock_seq_low 2 4 16 (1 to 3-bit "variant" in the most significant bits, followed by the 13 to 15-bit clock sequence )
node 6 12 48 the 48-bit node id (mac address value as default)
Total 16 32 128
UUID Record Layout

4.2 - Version 2 UUID

  • As in version 1, it generates UUID value based on current time (timestamp) and Mac address value (node)
  • Since the RFC document does not provide details for this version, its implementation and use are not very common.

4.3 - Version 3 UUID

  • In version 3, the UUID value is generated using the MD5 (128-bit) Hash algorithm with namespace and name values.
  • If the name and namespace values are given the same, it will produce the same UUID.
  • This version can be preferred in the need to generate UUID with the same value.

Note: I will show the UUID generation example with version 3 at the end of version 5.

4.4 - Version 4 UUID

  • In Version 4,  UUID is generated based on random values.
  • In Version 4 - Since the version number (4 bits) is fixed in the Variant 1 (2 bit) type, a total of 122 bits will be generated with random values. This can take  2122 so 5.3 x 1036  unique ids (UUIDs).
  • In Version 4 - Variant 2 (3 bits) can have  2121 random values in total. So, the variant 2 type can have half as many unique id values (UUID) as the variant 1 type in the UUID version 4.
  • In this version, when generating the UUID, it is very difficult to guess and repeat. Because it is not generated based on the Mac address, timestamp or name/namespace values.

4.4.1 - UUID generation with version 4;

PostgreDB

  • SELECT uuid_generate_v4();  

From Linux Terminal

  • uuidgen -r

"34779908-2848-4b2d-939d-df321b66a82b"
"8d9ee101-6229-4c88-be76-9502e6ac347a"
corresponding values are generated.

4.5 - UUID Version 5

  • As in version 3, it generates the UUID using the name and namespace values. The difference between version 3 and version 5 is that Version 5  -UUID is generated by the SHA-1 (160-bit) hash algorithm instead of MD5 (version 3).
  • Again, as in version 3, if the Name and namespace values are given the same, it will generate the same UUID value. This version can be preferred in the need to generate the same UUID value.
  • It is more secure than Version 3 because it uses the SHA-1 algorithm.

Namespace ve Name Values

The namespace and name values we mentioned in version 3 and version 5;

Namespace:

  • It is basically a UUID value. It can be any UUID value.
  • Predefined namespace UUID values are used in the standard implementations.
  • These namespace UUID values can be DNS, URL, OID or x500.

Name:

  • It can be any value.

Namespace UUID Values
According to the RFC 4122 document, the UUID values of the namespace field values we mentioned in Versions 3 and 5 are as follows;

  • NameSpace_DNS = 6ba7b810-9dad-11d1-80b4-00c04fd430c8
  • NameSpace_URL = 6ba7b811-9dad-11d1-80b4-00c04fd430c8
  • NameSpace_OID = 6ba7b812-9dad-11d1-80b4-00c04fd430c8
  • NameSpace_X500 = 6ba7b814-9dad-11d1-80b4-00c04fd430c8

Note: Name or namespace values cannot be determined by decoding the UUID values that are created with version 3 or 5.

4.6 - Generating UUID for versions 3 and 5

Version 3

Linux Terminal

PostgreDB

  • select uuid_generate_v3('6ba7b811-9dad-11d1-80b4-00c04fd430c8', 'https://volkandogan.net');
  • As the Namespace value, we have given the "URL" UUID value which is defined in the RFC document.
  • Let's give the "name" value as "https://volkandogan.net"
  • The generated UUID value will be "bfcc1da2-9196-3441-ae15-a311819c3f09".

Note: If we recreate it with the same namespace and name value then it will still generate the same UUID value.

Let's give the "name" value differently this time;

Linux Terminal

PostgreDB

"9b3c7828-2d27-3ff1-bffe-c1735d029086" UUID value will be generated.

Generating UUID with Version 5

Postgre DB

Linux Terminal

  • uuidgen -s --namespace 6ba7b811-9dad-11d1-80b4-00c04fd430c8 --name https://volkandogan.net  command;
  • As the Namespace value, we have given the "URL" UUID value which is defined in the RFC document.
  • When we set the name value with "https://volkandogan.net"; to generate
  • "dd3a9e4f-518a-510d-8e35-581198e605c1" UUID value will be generated.

Note: When we want to create it with the same values as in version 3, it will still generate the same UUID value.

Let's give the "name" value differently this time as in the version 3 example;

Postgre DB

Linux Terminal

"c5949a08-c739-5099-99c4-ccb5ee00ccc2" UUID value will be generated.

4.7 - Nil UUID

"Nil" UUID is a special value with all bit values set to zero.

When we run in PostgreDB - select uuid_nil();

  • 00000000-0000-0000-0000-000000000000

Conclusion;

In this article, we have explored versions and variants of the UUID and how to understand them from the UUID value. We also generated a few UUIDs with some UUID versions and looked at some details.


Resources;

https://en.wikipedia.org/wiki/Universally_unique_identifier
https://datatracker.ietf.org/doc/html/rfc4122
https://www.postgresql.org/docs/9.4/uuid-ossp.html
https://man7.org/linux/man-pages/man1/uuidgen.1.html