Java UUID Generator Example
howtodoinjava

Learn what is UUID and it’s versions and variants. Learn to generate UUID in Java using UUID.randomUUID() API. Also learn to generate version 5 UUID in Java.

1. What is UUID?

UUID (Universally Unique IDentifier), also known as GUID (Globally Unique IDentifier) is 128 bits long identifier that is unique across both space and time, with respect to the space of all other UUIDs. It requires no central registration process. As a result, generation on demand can be completely automated, and used for a variety of purposes.

To understand how unique is a UUID, you should know that UUID generation algorithms support very high allocation rates of up to 10 million per second per machine if necessary, so that they could even be used as transaction IDs.

We can apply sorting, ordering and we can store them in databases. It makes it useful in programming in general.

Since UUIDs are unique and persistent, they make excellent Uniform Resource Names (URNs) with lowest mining cost in comparison to other alternatives.

The nil UUID is special form of UUID that is specified to have all 128 bits set to zero.

Do not assume that UUIDs are hard to guess; they should not be used as security capabilities. A predictable random number source will exacerbate the situation. Humans do not have the ability to easily check the integrity of a UUID by simply glancing at it.

2. UUID Types

A typical UID is displayed in 5 groups separated by hyphens, in the form 8-4-4-4-12 for a total of 36 characters (32 alphanumeric characters and 4 hyphens).

123e4567-e89b-12d3-a456-426655440000
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

Here 'M' indicate the UUID version and 'N' indicate the UUID variant.

  • The variant field contains a value which identifies the layout of the UUID.
  • The version field holds a value that describes the type of this UUID. There are five different basic types of UUIDs.
    1. Time-Based UUID (Version 1) – generated from a time and a node id
    2. DCE (Distributed Computing Environment) security (Version 2) – generated from an identifier (usually a group or user id), time, and a node id
    3. Name-based (Version 3) – generated by MD5 (128 bits) hashing of a namespace identifier and name
    4. Randomly generated UUIDs (Version 4) – generated using a random or pseudo-random number
    5. Name-based using SHA-1 hashing (Version 5) Recommended – generated by SHA-1 (160 bits) hashing of a namespace identifier and name. Java does not provide its implementation. We shall create our own.

3. Java UUID Example

3.1. UUID.randomUUID() – Version 4

Default API randomUUID() is a static factory to retrieve a type 4 (pseudo randomly generated) UUID. It is good enough for most of the usecases.

UUID uuid = UUID.randomUUID();
		
System.out.println(uuid);
System.out.println(uuid.variant());		//2
System.out.println(uuid.version());		//4

Program output.

17e3338d-344b-403c-8a87-f7d8006d6e33
2
4

3.2. Generate Version 5 UUID

Java does not provide inbuilt API to generate version 5 UUID, so we have to create our own implementation. Below is one such implementation. (Ref).

import java.nio.ByteOrder;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

public class UUID5 
{
	public static UUID fromUTF8(String name) {
		return fromBytes(name.getBytes(Charset.forName("UTF-8")));
	}
	
	private static UUID fromBytes(byte[] name) {
		if (name == null) {
			throw new NullPointerException("name == null");
		}
		try {
			MessageDigest md = MessageDigest.getInstance("SHA-1");
			return makeUUID(md.digest(name), 5);
		} catch (NoSuchAlgorithmException e) {
			throw new AssertionError(e);
		}
	}
	
	private static UUID makeUUID(byte[] hash, int version) {
		long msb = peekLong(hash, 0, ByteOrder.BIG_ENDIAN);
		long lsb = peekLong(hash, 8, ByteOrder.BIG_ENDIAN);
		// Set the version field
		msb &= ~(0xfL << 12);
		msb |= ((long) version) << 12;
		// Set the variant field to 2
		lsb &= ~(0x3L << 62);
		lsb |= 2L << 62;
		return new UUID(msb, lsb);
	}
	
	private static long peekLong(final byte[] src, final int offset, final ByteOrder order) {
		long ans = 0;
		if (order == ByteOrder.BIG_ENDIAN) {
			for (int i = offset; i < offset + 8; i += 1) {
				ans <<= 8;
				ans |= src[i] & 0xffL;
			}
		} else {
			for (int i = offset + 7; i >= offset; i -= 1) {
				ans <<= 8;
				ans |= src[i] & 0xffL;
			}
		}
		return ans;
	}
}
UUID uuid = UUID5.fromUTF8("954aac7d-47b2-5975-9a80-37eeed186527");

System.out.println(uuid);
System.out.println(uuid.variant());
System.out.println(uuid.version());
d1d16b54-9757-5743-86fa-9ffe3b937d78
2
5

Drop me your questions related to generating UUID in Java.

Happy Learning !!

Ref : Rfc 4122