From 21c735364eaed5b54e6b0096147fe21c04303da7 Mon Sep 17 00:00:00 2001 From: Harry9656 Date: Wed, 23 Nov 2022 18:32:29 +0100 Subject: [PATCH] [JAVA-4543]: Improve Guide to UUID in Java (#12962) Co-authored-by: Harpal Singh --- .../java/com/baeldung/uuid/UUIDGenerator.java | 49 ++++++------------- .../baeldung/uuid/UUIDGeneratorUnitTest.java | 20 ++++++-- 2 files changed, 29 insertions(+), 40 deletions(-) diff --git a/core-java-modules/core-java-uuid/src/main/java/com/baeldung/uuid/UUIDGenerator.java b/core-java-modules/core-java-uuid/src/main/java/com/baeldung/uuid/UUIDGenerator.java index 264744dcba..2170a72644 100644 --- a/core-java-modules/core-java-uuid/src/main/java/com/baeldung/uuid/UUIDGenerator.java +++ b/core-java-modules/core-java-uuid/src/main/java/com/baeldung/uuid/UUIDGenerator.java @@ -3,8 +3,6 @@ package com.baeldung.uuid; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.time.Duration; -import java.time.LocalDateTime; import java.util.Arrays; import java.util.Random; import java.util.UUID; @@ -13,7 +11,8 @@ public final class UUIDGenerator { private static final char[] hexArray = "0123456789ABCDEF".toCharArray(); - private UUIDGenerator() {} + private UUIDGenerator() { + } /** * Type 1 UUID Generation @@ -33,14 +32,12 @@ public final class UUIDGenerator { } private static long get64MostSignificantBitsForVersion1() { - final LocalDateTime start = LocalDateTime.of(1582, 10, 15, 0, 0, 0); - final Duration duration = Duration.between(start, LocalDateTime.now()); - final long seconds = duration.getSeconds(); - final long nanos = duration.getNano(); - final long timeForUuidIn100Nanos = seconds * 10000000 + nanos * 100; - final long least12SignificantBitOfTime = (timeForUuidIn100Nanos & 0x000000000000FFFFL) >> 4; + final long timeForUuidIn100Nanos = System.currentTimeMillis(); + final long time_low = (timeForUuidIn100Nanos & 0x0000_0000_FFFF_FFFFL) << 32; + final long time_mid = ((timeForUuidIn100Nanos >> 32) & 0xFFFF) << 16; 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,32 +91,14 @@ public final class UUIDGenerator { long lsb = 0; 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 = 8; i < 16; i++) {lsb = (lsb << 8) | (data[i] & 0xff);} - 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]; + for (int i = 0; i < 8; i++) { + msb = (msb << 8) | (data[i] & 0xff); } - return new String(hexChars); + + for (int i = 8; i < 16; i++) { + lsb = (lsb << 8) | (data[i] & 0xff); + } + return new UUID(msb, lsb); } private static byte[] bytesFromUUID(String uuidHexString) { diff --git a/core-java-modules/core-java-uuid/src/test/java/com/baeldung/uuid/UUIDGeneratorUnitTest.java b/core-java-modules/core-java-uuid/src/test/java/com/baeldung/uuid/UUIDGeneratorUnitTest.java index cf0d7656ff..3c85eee3ff 100644 --- a/core-java-modules/core-java-uuid/src/test/java/com/baeldung/uuid/UUIDGeneratorUnitTest.java +++ b/core-java-modules/core-java-uuid/src/test/java/com/baeldung/uuid/UUIDGeneratorUnitTest.java @@ -3,6 +3,10 @@ package com.baeldung.uuid; import org.junit.jupiter.api.Test; 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 static org.junit.jupiter.api.Assertions.assertEquals; @@ -13,17 +17,23 @@ class UUIDGeneratorUnitTest { private static final String NAMESPACE_DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"; @Test - public void version_1_UUID_is_generated_with_correct_length_version_and_variant() { - + void shouldGenerateType1UUIDWithCorrectVersionAndVariant() { UUID uuid = UUIDGenerator.generateType1UUID(); - assertEquals(36, uuid.toString().length()); assertEquals(1, uuid.version()); assertEquals(2, uuid.variant()); } @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"); @@ -33,7 +43,7 @@ class UUIDGeneratorUnitTest { } @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");