[uuid] Added method to generate UUID identifiers for version 5 (#10948)
Signed-off-by: Diego Torres <dtorres.py@gmail.com>
This commit is contained in:
parent
0c656299d0
commit
f66bfa5088
@ -1,6 +1,8 @@
|
||||
package com.baeldung.uuid;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.time.Duration;
|
||||
@ -132,21 +134,21 @@ public class UUIDGenerator {
|
||||
}
|
||||
|
||||
private static byte[] bytesFromUUID(String uuidHexString) {
|
||||
String normalizedUUIDHexString = uuidHexString.replace("-","");
|
||||
String normalizedUUIDHexString = uuidHexString.replace("-", "");
|
||||
|
||||
assert normalizedUUIDHexString.length() == 32;
|
||||
|
||||
byte[] bytes = new byte[16];
|
||||
for (int i = 0; i < 16; i++) {
|
||||
byte b = hexToByte(normalizedUUIDHexString.substring(i*2, i*2+2));
|
||||
byte b = hexToByte(normalizedUUIDHexString.substring(i * 2, i * 2 + 2));
|
||||
bytes[i] = b;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static byte hexToByte(String hexString) {
|
||||
int firstDigit = Character.digit(hexString.charAt(0),16);
|
||||
int secondDigit = Character.digit(hexString.charAt(1),16);
|
||||
int firstDigit = Character.digit(hexString.charAt(0), 16);
|
||||
int secondDigit = Character.digit(hexString.charAt(1), 16);
|
||||
return (byte) ((firstDigit << 4) + secondDigit);
|
||||
}
|
||||
|
||||
@ -154,14 +156,54 @@ public class UUIDGenerator {
|
||||
int finalLength = byteArray1.length + byteArray2.length;
|
||||
byte[] result = new byte[finalLength];
|
||||
|
||||
for(int i = 0; i < byteArray1.length; i++) {
|
||||
for (int i = 0; i < byteArray1.length; i++) {
|
||||
result[i] = byteArray1[i];
|
||||
}
|
||||
|
||||
for(int i = 0; i < byteArray2.length; i++) {
|
||||
result[byteArray1.length+i] = byteArray2[i];
|
||||
for (int i = 0; i < byteArray2.length; i++) {
|
||||
result[byteArray1.length + i] = byteArray2[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static UUID generateType5UUID(String name) {
|
||||
|
||||
try {
|
||||
|
||||
byte[] bytes = name.getBytes(StandardCharsets.UTF_8);
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-1");
|
||||
|
||||
byte[] hash = md.digest(bytes);
|
||||
|
||||
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) 5) << 12;
|
||||
// Set the variant field to 2
|
||||
lsb &= ~(0x3L << 62);
|
||||
lsb |= 2L << 62;
|
||||
return new UUID(msb, lsb);
|
||||
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -61,4 +61,14 @@ class UUIDGeneratorUnitTest {
|
||||
assertEquals(5, uuid.version());
|
||||
assertEquals(2, uuid.variant());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void version_5_UUID_is_correctly_generated_for_domain_baeldung_com_without_namespace() throws UnsupportedEncodingException {
|
||||
|
||||
UUID uuid = UUIDGenerator.generateType5UUID("baeldung.com");
|
||||
|
||||
assertEquals("a3c27ab0-2b46-55ef-b50e-0e5c57bfea94", uuid.toString());
|
||||
assertEquals(5, uuid.version());
|
||||
assertEquals(2, uuid.variant());
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user