[JAVA-4543]: Improve Guide to UUID in Java (#12962)

Co-authored-by: Harpal Singh <harpal.singh@kaleyra.com>
This commit is contained in:
Harry9656 2022-11-23 18:32:29 +01:00 committed by GitHub
parent 0ecc5b2c11
commit 21c735364e
2 changed files with 29 additions and 40 deletions

View File

@ -3,8 +3,6 @@ package com.baeldung.uuid;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Arrays; import java.util.Arrays;
import java.util.Random; import java.util.Random;
import java.util.UUID; import java.util.UUID;
@ -13,7 +11,8 @@ public final class UUIDGenerator {
private static final char[] hexArray = "0123456789ABCDEF".toCharArray(); private static final char[] hexArray = "0123456789ABCDEF".toCharArray();
private UUIDGenerator() {} private UUIDGenerator() {
}
/** /**
* Type 1 UUID Generation * Type 1 UUID Generation
@ -33,14 +32,12 @@ public final class UUIDGenerator {
} }
private static long get64MostSignificantBitsForVersion1() { private static long get64MostSignificantBitsForVersion1() {
final LocalDateTime start = LocalDateTime.of(1582, 10, 15, 0, 0, 0); final long timeForUuidIn100Nanos = System.currentTimeMillis();
final Duration duration = Duration.between(start, LocalDateTime.now()); final long time_low = (timeForUuidIn100Nanos & 0x0000_0000_FFFF_FFFFL) << 32;
final long seconds = duration.getSeconds(); final long time_mid = ((timeForUuidIn100Nanos >> 32) & 0xFFFF) << 16;
final long nanos = duration.getNano();
final long timeForUuidIn100Nanos = seconds * 10000000 + nanos * 100;
final long least12SignificantBitOfTime = (timeForUuidIn100Nanos & 0x000000000000FFFFL) >> 4;
final long version = 1 << 12; final long version = 1 << 12;
return (timeForUuidIn100Nanos & 0xFFFFFFFFFFFF0000L) + version + least12SignificantBitOfTime; final long time_hi = ((timeForUuidIn100Nanos >> 48) & 0x0FFF);
return time_low + time_mid + version + time_hi;
} }
/** /**
@ -94,34 +91,16 @@ public final class UUIDGenerator {
long lsb = 0; long lsb = 0;
assert data.length == 16 : "data must be 16 bytes in length"; assert data.length == 16 : "data must be 16 bytes in length";
for (int i = 0; i < 8; i++) {msb = (msb << 8) | (data[i] & 0xff);} 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);} for (int i = 8; i < 16; i++) {
lsb = (lsb << 8) | (data[i] & 0xff);
}
return new UUID(msb, lsb); return new UUID(msb, lsb);
} }
/**
* Unique Keys Generation Using Message Digest and Type 4 UUID
* @throws NoSuchAlgorithmException
*/
public static String generateUniqueKeysWithUUIDAndMessageDigest() throws NoSuchAlgorithmException {
final MessageDigest salt = MessageDigest.getInstance("SHA-256");
salt.update(UUID.randomUUID()
.toString()
.getBytes(StandardCharsets.UTF_8));
return bytesToHex(salt.digest());
}
private static String bytesToHex(byte[] bytes) {
final char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
final int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
private static byte[] bytesFromUUID(String uuidHexString) { private static byte[] bytesFromUUID(String uuidHexString) {
final String normalizedUUIDHexString = uuidHexString.replace("-", ""); final String normalizedUUIDHexString = uuidHexString.replace("-", "");

View File

@ -3,6 +3,10 @@ package com.baeldung.uuid;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.UUID; import java.util.UUID;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
@ -13,17 +17,23 @@ class UUIDGeneratorUnitTest {
private static final String NAMESPACE_DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"; private static final String NAMESPACE_DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
@Test @Test
public void version_1_UUID_is_generated_with_correct_length_version_and_variant() { void shouldGenerateType1UUIDWithCorrectVersionAndVariant() {
UUID uuid = UUIDGenerator.generateType1UUID(); UUID uuid = UUIDGenerator.generateType1UUID();
assertEquals(36, uuid.toString().length()); assertEquals(36, uuid.toString().length());
assertEquals(1, uuid.version()); assertEquals(1, uuid.version());
assertEquals(2, uuid.variant()); assertEquals(2, uuid.variant());
} }
@Test @Test
public void version_3_UUID_is_correctly_generated_for_domain_baeldung_com() throws UnsupportedEncodingException { void shouldGenerateType1UUIDWithTheCurrentDate() {
UUID uuid = UUIDGenerator.generateType1UUID();
long time = uuid.timestamp();
LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault());
assertEquals(LocalDate.now(), dateTime.toLocalDate());
}
@Test
void version_3_UUID_is_correctly_generated_for_domain_baeldung_com() {
UUID uuid = UUIDGenerator.generateType3UUID(NAMESPACE_DNS, "baeldung.com"); UUID uuid = UUIDGenerator.generateType3UUID(NAMESPACE_DNS, "baeldung.com");
@ -33,7 +43,7 @@ class UUIDGeneratorUnitTest {
} }
@Test @Test
public void version_3_UUID_is_correctly_generated_for_domain_d() throws UnsupportedEncodingException { void version_3_UUID_is_correctly_generated_for_domain_d() {
UUID uuid = UUIDGenerator.generateType3UUID(NAMESPACE_DNS, "d"); UUID uuid = UUIDGenerator.generateType3UUID(NAMESPACE_DNS, "d");