In python, to make a Type 5 UUID we can simply do:
import uuid
print uuid.uuid5(uuid.NAMESPACE_URL, 'my string')
Looking through the java documentation for java.util.UUID, I don't see how to do it. First off, type 5 isn't mentioned. They do have a Type 3, but the signature is:
nameUUIDFromBytes(byte[] name)
Static factory to retrieve a type 3 (name based) UUID based on the specified byte array.
How can we make a Type 5 UUID in Java?
uuid5(namespace, string) : This function uses SHA-1 hash value of namespaces mentioned with a string to generate a random id of that particular string.
A UUID is a class that represents an immutable Universally Unique Identifier (UUID). A UUID represents a 128-bit long value that is unique to all practical purpose. It is used to identify information in the computer system. The UUID class belongs to java. util package.
You can implement it yourself by following the code proposed in https://stackoverflow.com/a/28776880/1452094. However this does require some fiddling since the j.u.UUID constructor takes longs.
As of Java 8
the standard library does not seem to support type 5. But third party libraries like "Apache Commons Id" have UUID implementations that do support it.
EDIT: Here is a fully functional implementation:
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Objects;
import java.util.UUID;
public class UUIDType5 {
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;
}
}
To verify it works I ran the following code:
public static void main(String[] args) {
UUID test = UUIDType5.nameUUIDFromNamespaceAndString(NAMESPACE_URL, "google.com");
System.out.println(test);
System.out.println(test.version());
}
This created the output:
fedb2fa3-8f5c-5189-80e6-f563dd1cb8f9
5
Verified against the official python implementation:
>>> print(uuid.uuid5(uuid.NAMESPACE_URL, 'google.com'))
fedb2fa3-8f5c-5189-80e6-f563dd1cb8f9
In the case someone else needs a library that generates version 5 UUIDs.
UUID uuid = UuidCreator.getNameBasedSha1("google.com");
UUID uuid = UuidCreator.getNameBasedSha1(UuidCreator.NAMESPACE_URL, "google.com");
https://github.com/f4b6a3/uuid-creator
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With