Generate UUID in Java: Best Implementation

Today we will be looking at how we can generate UUID in Java. Using no additional external libraries.

You must have already known that there are more than one UUID versions. So we are going to cover it version by topic.

But today prior to version 4 are not in use anymore so let us look at version 4 and version 5.

Generate UUID4 in Java

This version of UUID is the most widely used. Here is the code for generating UUID version 4.

Generating random UUID

import java.util.UUID;

public class UuidHelper {

    public static String getUuid4() {
        return UUID.randomUUID().toString();
    }

}Code language: Java (java)

If you did not understand what we did above. Let me provide you a little context. We have a UUID class that has .randomUUID(). It will provide us an instance of UUID class.

To convert it to string we just have to use the .toString() method.

Generating UUID from string

If you have a string and you want to instantiate a UUID instance. You should use .fromString() method like below.

The use case for this is really rare. But if you want to you can use the following code.

import java.util.UUID;

public class UuidHelper {

    public static UUID getUuid4(String uuid) {
        return UUID.fromString(uuid);
    }

}Code language: JavaScript (javascript)

If the UUID is invalid then it will throw an IllegalArgumentException.

Generate UUID5 in Java

UUID5 is very different from UUID4 in implementation. It is because UUID5 makes us define namespace for usage.

Because of this we have to borrow the implementation from exiting utilities. I have borrowed code from Apache Commons.

Since this is not an official implementation. We will not be doing things as we have done above. We will just use the UUID5 string representation.

And if you are wondering if you need version 5. The simple answer is you don’t. But anyway here is the implementation.


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

public class Uuid5 {

    private static final Charset UTF8 = Charset.forName("UTF-8");
    public static final UUID NAMESPACE_DNS = UUID.fromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8");
    public static final UUID NAMESPACE_URL = UUID.fromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8");
    public static final UUID NAMESPACE_OID = UUID.fromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8");
    public static final UUID NAMESPACE_X500 = UUID.fromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8");

    public static UUID nameUUIDFromNamespaceAndString(UUID namespace, String name) {
        return nameUUIDFromNamespaceAndBytes(namespace, Objects.requireNonNull(name, "name == null").getBytes(UTF8));
    }

    public static UUID nameUUIDFromNamespaceAndBytes(UUID namespace, byte[] name) {
        MessageDigest md;
        try {
            md = MessageDigest.getInstance("SHA-1");
        } catch (NoSuchAlgorithmException nsae) {
            throw new InternalError("SHA-1 not supported");
        }
        md.update(toBytes(Objects.requireNonNull(namespace, "namespace is null")));
        md.update(Objects.requireNonNull(name, "name is null"));
        byte[] sha1Bytes = md.digest();
        sha1Bytes[6] &= 0x0f;  /* clear version        */
        sha1Bytes[6] |= 0x50;  /* set to version 5     */
        sha1Bytes[8] &= 0x3f;  /* clear variant        */
        sha1Bytes[8] |= 0x80;  /* set to IETF variant  */
        return fromBytes(sha1Bytes);
    }

    private static UUID fromBytes(byte[] data) {
        // Based on the private UUID(bytes[]) constructor
        long msb = 0;
        long lsb = 0;
        assert data.length >= 16;
        for (int i = 0; i < 8; i++)
            msb = (msb << 8) | (data[i] & 0xff);
        for (int i = 8; i < 16; i++)
            lsb = (lsb << 8) | (data[i] & 0xff);
        return new UUID(msb, lsb);
    }

    private static byte[] toBytes(UUID uuid) {
        // inverted logic of fromBytes()
        byte[] out = new byte[16];
        long msb = uuid.getMostSignificantBits();
        long lsb = uuid.getLeastSignificantBits();
        for (int i = 0; i < 8; i++)
            out[i] = (byte) ((msb >> ((7 - i) * 8)) & 0xff);
        for (int i = 8; i < 16; i++)
            out[i] = (byte) ((lsb >> ((15 - i) * 8)) & 0xff);
        return out;
    }

}
Code language: Java (java)

Also here is a simple usage for the implementation above.

class UuidTest {
    public void testUuid5() {
        UUID test = Uuid5.nameUUIDFromNamespaceAndString(Uuid5.NAMESPACE_URL, "techenum.com");
        System.out.println(test);
        System.out.println(test.version());
    }
}Code language: Java (java)

So that’s how we generate UUID in Java.

Recommended

Java List Data Structure: Learn Real Use Case Of List

Android Intent: Learn Implicit Intent and Explicit Intent

Push Notifications in Android Using One Signal

Manage Multiple Git Account using SSH, in One Device

Android Notification Manager: Create Notification in Android

Related Posts