diff --git a/core-java-modules/core-java-uuid/src/main/java/com/baeldung/uuid/UUIDPositiveLongGenerator.java b/core-java-modules/core-java-uuid/src/main/java/com/baeldung/uuid/UUIDPositiveLongGenerator.java new file mode 100644 index 0000000000..eb3a511256 --- /dev/null +++ b/core-java-modules/core-java-uuid/src/main/java/com/baeldung/uuid/UUIDPositiveLongGenerator.java @@ -0,0 +1,83 @@ +package com.baeldung.uuid; + +import java.nio.ByteBuffer; +import java.security.SecureRandom; +import java.util.UUID; + +/** + * Methods are called by reflection in the unit test + */ +@SuppressWarnings("unused") +public class UUIDPositiveLongGenerator { + public long getLeastSignificantBits() { + return Math.abs(UUID.randomUUID().getLeastSignificantBits()); + } + + public long getMostSignificantBits() { + return Math.abs(UUID.randomUUID().getMostSignificantBits()); + } + + public long combineByteBuffer() { + UUID uuid = UUID.randomUUID(); + ByteBuffer bb = ByteBuffer.wrap(new byte[16]); + bb.putLong(uuid.getMostSignificantBits()); + bb.putLong(uuid.getLeastSignificantBits()); + bb.rewind(); + return Math.abs(bb.getLong()); + } + + public long combineBitwise() { + UUID uniqueUUID = UUID.randomUUID(); + long mostSignificantBits = uniqueUUID.getMostSignificantBits(); + long leastSignificantBits = uniqueUUID.getLeastSignificantBits(); + return Math.abs((mostSignificantBits << 32) | (leastSignificantBits & 0xFFFFFFFFL)); + } + + public long combineDirect() { + UUID uniqueUUID = UUID.randomUUID(); + long mostSignificantBits = uniqueUUID.getMostSignificantBits(); + long leastSignificantBits = uniqueUUID.getLeastSignificantBits(); + return Math.abs(mostSignificantBits ^ (leastSignificantBits >> 1)); + } + + public long combinePermutation() { + UUID uuid = UUID.randomUUID(); + long mostSigBits = uuid.getMostSignificantBits(); + long leastSigBits = uuid.getLeastSignificantBits(); + byte[] uuidBytes = new byte[16]; + + for (int i = 0; i < 8; i++) { + uuidBytes[i] = (byte) (mostSigBits >>> (8 * (7 - i))); + uuidBytes[i + 8] = (byte) (leastSigBits >>> (8 * (7 - i))); + } + + long result = 0; + for (byte b : uuidBytes) { + result = (result << 8) | (b & 0xFF); + } + return Math.abs(result); + } + + public long combineWithSecureRandom() { + UUID uniqueUUID = UUID.randomUUID(); + SecureRandom secureRandom = new SecureRandom(); + long randomBits = secureRandom.nextLong(); + + long mostSignificantBits = uniqueUUID.getMostSignificantBits() ^ randomBits; + long leastSignificantBits = uniqueUUID.getLeastSignificantBits(); + + return Math.abs((mostSignificantBits << 32) | (leastSignificantBits & 0xFFFFFFFFL)); + } + + public long combineWithNanoTime() { + UUID uniqueUUID = UUID.randomUUID(); + long nanoTime = System.nanoTime(); + + long mostSignificantBits = uniqueUUID.getMostSignificantBits() ^ nanoTime; + long leastSignificantBits = uniqueUUID.getLeastSignificantBits(); + + return Math.abs((mostSignificantBits << 32) | (leastSignificantBits & 0xFFFFFFFFL)); + } + + +} diff --git a/core-java-modules/core-java-uuid/src/test/java/com/baeldung/uuid/UUIDPositiveLongGeneratorUnitTest.java b/core-java-modules/core-java-uuid/src/test/java/com/baeldung/uuid/UUIDPositiveLongGeneratorUnitTest.java new file mode 100644 index 0000000000..a4d57b19c2 --- /dev/null +++ b/core-java-modules/core-java-uuid/src/test/java/com/baeldung/uuid/UUIDPositiveLongGeneratorUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.uuid; + +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Method; +import java.util.HashSet; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; + +public class UUIDPositiveLongGeneratorUnitTest { + + private final UUIDPositiveLongGenerator uuidLongGenerator = new UUIDPositiveLongGenerator(); + + private final Set uniqueValues = new HashSet<>(); + + @Test + void whenForeachMethods_thenRetryWhileNotUnique() throws Exception { + for (Method method : uuidLongGenerator.getClass().getDeclaredMethods()) { + long uniqueValue; + do uniqueValue = (long) method.invoke(uuidLongGenerator); while (!isUnique(uniqueValue)); + assertThat(uniqueValue).isPositive(); + } + } + + @Test + void whenGivenLongValue_thenCheckUniqueness() { + long uniqueValue = generateUniqueLong(); + assertThat(uniqueValue).isPositive(); + } + + private long generateUniqueLong() { + long uniqueValue; + do uniqueValue = uuidLongGenerator.combineBitwise(); while (!isUnique(uniqueValue)); + return uniqueValue; + } + + private boolean isUnique(long value) { + // Implement uniqueness checking logic, for example, by checking in the database + return uniqueValues.add(value); + } + +} diff --git a/core-java-modules/core-java-uuid/src/test/resources/logback.xml b/core-java-modules/core-java-uuid/src/test/resources/logback.xml index 56af2d397e..a076f8db47 100644 --- a/core-java-modules/core-java-uuid/src/test/resources/logback.xml +++ b/core-java-modules/core-java-uuid/src/test/resources/logback.xml @@ -2,8 +2,7 @@ - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n