The UUID.nameUUIDFromBytes()
method doesn't use a namespace to generate UUIDs v3. It just hashes the 'name' using MD5.
You must manually concatenate the namespace bytes (16 bytes) with the 'name' bytes. The 2 examples below use ByteBuffer
and System.arraycopy()
to concatenate 'namespace' and 'name' before calling UUID.nameUUIDFromBytes()
.
Example using 'ByteBuffer'
package com.example;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
public class Example1 {
/**
* Returns a name-based UUID v3 using a namespace.
*
* @param namespace a UUID
* @param name a string
* @return a UUID
*/
public static UUID getNameBased(UUID namespace, String name) {
// 1. Get the NAMESPACE bytes
final byte[] nameBytes = name.getBytes(StandardCharsets.UTF_8);
// 2. Concatenate NAMESPACE and NAME bytes
ByteBuffer buffer = ByteBuffer.allocate(nameBytes.length + 16);
buffer.putLong(namespace.getMostSignificantBits());
buffer.putLong(namespace.getLeastSignificantBits());
buffer.put(nameBytes);
// 3. Generate a name-based UUID
return UUID.nameUUIDFromBytes(buffer.array());
}
public static void main(String[] args) {
UUID namespace = UUID.fromString("11111111-2222-3333-4444-555555555555");
String name = "this is a test";
UUID uuid = getNameBased(namespace, name);
System.out.println(uuid); // prints: 04334e59-716d-3078-9722-63e2ec20d4ec
}
}
Example using 'System.arraycopy()'
package com.example;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
public class Example2 {
/**
* Returns a name-based UUID v3 using a namespace.
*
* @param namespace a UUID
* @param name a string
* @return a UUID
*/
public static UUID getNameBased(UUID namespace, String name) {
// 1. Get NAMESPACE and NAME bytes
final byte[] msb = toBytes(namespace.getMostSignificantBits());
final byte[] lsb = toBytes(namespace.getLeastSignificantBits());
final byte[] nam = name.getBytes(StandardCharsets.UTF_8);
// 2. Concatenate NAMESPACE and NAME bytes
final byte[] bytes = new byte[16 + nam.length];
System.arraycopy(msb, 0, bytes, 0, 8);
System.arraycopy(lsb, 0, bytes, 8, 8);
System.arraycopy(nam, 0, bytes, 16, nam.length);
// 3. Generate a name-based UUID
return UUID.nameUUIDFromBytes(bytes);
}
private static byte[] toBytes(final long number) {
return new byte[] { (byte) (number >>> 56), (byte) (number >>> 48), (byte) (number >>> 40),
(byte) (number >>> 32), (byte) (number >>> 24), (byte) (number >>> 16), (byte) (number >>> 8),
(byte) (number) };
}
public static void main(String[] args) {
UUID namespace = UUID.fromString("11111111-2222-3333-4444-555555555555");
String name = "this is a test";
UUID uuid = getNameBased(namespace, name);
System.out.println(uuid); // prints: 04334e59-716d-3078-9722-63e2ec20d4ec
}
}
Libraries
There are 2 libraries that can generate UUIDs v3 and v5 using namespaces: