If you’re working with Spring, check out "REST With Spring":

>> CHECK OUT THE COURSE

1. Overview

UUID (Universally Unique Identifier), also known as GUID (Globally Unique Identifier) represents a 128-bit long value which guarantees uniqueness across time and space. The standard representation of the UUID uses hex digits (octets): 

123e4567-e89b-12d3-a456-556642440000

The Nil UUID is a special form of UUID in which all bits are set to zero.

In this article, we will have a look at the UUID class in Java.

2. Structure

Let’s take the example UUID:

123e4567-e89b-42d3-a456-556642440000
xxxxxxxx-xxxx-Bxxx-Axxx-xxxxxxxxxxxx

A represents the variant which determines the layout of the UUID. All other bits in the UUID depends on the setting of the bits in the variant field. The variant is determined by 3 most significant bit of A:

  MSB1    MSB2    MSB3
   0       X       X     reserved (0)
   1       0       X     current variant (2)
   1       1       0     reserved for Microsoft (6)
   1       1       1     reserved for future (7)

A‘s value in the mentioned UUID is ‘a’. The binary equivalent of ‘a’ (=10xx) shows variant as 2.
B represents the version. The version in the mentioned UUID (value of B) is 4.

Java provides methods for getting variant and version of UUID:

UUID uuid = UUID.randomUUID();
int variant = uuid.variant();
int version = uuid.version();

These are 5 different versions for variant 2 UUIDs: Time Based (UUIDv1), DCE Security (UUIDv2), Name Based (UUIDv3 and UUIDv5), Random (UUIDv4).

Java provides an implementation for the v3 and v4, but also provides a constructor for generating any type of UUID:

UUID uuid = new UUID(long mostSigBits, long leastSigBits);

2.1. Version 3 & 5

The UUIDs are generated using the hash of namespace and name. The namespace identifiers are UUIDs like Domain Name System (DNS), Object Identifiers (OIDs), URLs etc.

UUID = hash(NAMESPACE_IDENTIFIER + NAME)

The only difference between UUIDv3 and UUIDv5 is the Hashing Algorithm – v3 uses MD5 (128 bits) while v5 uses SHA-1 (160 bits).

Simply put, we truncate the resulting hash to 128-bits and then replace 4 bit for the version and 2 bit for the variant.

Let’s generate type 3 UUID:

String source = namespace + name;
byte[] bytes = source.getBytes("UTF-8");
UUID uuid = UUID.nameUUIDFromBytes(bytes);

Java doesn’t provide the implementation for type 5. Check our source code repository for the UUIDv5.

2.2. Version 4

The UUID v4 implementation uses random numbers as the source. The Java implementation is SecureRandom – which uses an unpredictable value as the seed to generate random numbers to reduce the chance of collisions.

Let’s generate version 4 UUID:

UUID uuid = UUID.randomUUID();

Let’s generate a unique key using ‘SHA-256’ and a random UUID:

MessageDigest salt = MessageDigest.getInstance("SHA-256");
salt.update(UUID.randomUUID().toString().getBytes("UTF-8"));
String digest = bytesToHex(salt.digest());

3. Conclusion

Both UUIDv3 and UUIDv5 have the nice property that different systems can generate the same UUID using the same namespace and name. These are basically used for creating hierarchical UUIDs.

As both the hash functions MD5 and SHA1 have both been broken, using v5 is recommended. If you just need simple UUID generation, type 4 can be OK for the general use-case.

And, as always, the source code of implementation is available over on Github.

The new Certification Class of "REST With Spring" is finally out:

>> CHECK OUT THE COURSE