[Update] remove hashCode, add nano & secure
This commit is contained in:
commit
7bc08e8e74
@ -1,6 +1,7 @@
|
||||
package com.baeldung.uuid;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
@ -16,10 +17,6 @@ public class UUIDPositiveLongGenerator {
|
||||
return Math.abs(UUID.randomUUID().getMostSignificantBits());
|
||||
}
|
||||
|
||||
public long getHashCode() {
|
||||
return Math.abs(UUID.randomUUID().toString().hashCode());
|
||||
}
|
||||
|
||||
public long combineByteBuffer() {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
|
||||
@ -30,9 +27,10 @@ public class UUIDPositiveLongGenerator {
|
||||
}
|
||||
|
||||
public long combineBitwise() {
|
||||
UUID uniqueUUID;
|
||||
uniqueUUID = UUID.randomUUID();
|
||||
return Math.abs((uniqueUUID.getMostSignificantBits() << 32) | (uniqueUUID.getLeastSignificantBits() & 0xFFFFFFFFL));
|
||||
UUID uniqueUUID = UUID.randomUUID();
|
||||
long mostSignificantBits = uniqueUUID.getMostSignificantBits();
|
||||
long leastSignificantBits = uniqueUUID.getLeastSignificantBits();
|
||||
return Math.abs((mostSignificantBits << 32) | (leastSignificantBits & 0xFFFFFFFFL));
|
||||
}
|
||||
|
||||
public long combineDirect() {
|
||||
@ -59,4 +57,27 @@ public class UUIDPositiveLongGenerator {
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,52 +1,43 @@
|
||||
package com.baeldung.uuid;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class UUIDPositiveLongGeneratorUnitTest {
|
||||
private final static int NUMBER_OF_CHECKS = 1000000;
|
||||
private final static double COLLISION_THRESHOLD = 0.001;
|
||||
|
||||
private final UUIDPositiveLongGenerator uuidLongGenerator = new UUIDPositiveLongGenerator();
|
||||
private final Logger logger = LoggerFactory.getLogger(UUIDPositiveLongGeneratorUnitTest.class);
|
||||
|
||||
private final Set<Long> uniqueValues = new HashSet<>();
|
||||
|
||||
@Test
|
||||
void whenForeachGenerateLongValue_thenCollisionsCheck() throws Exception {
|
||||
printTableHeader();
|
||||
void whenForeachMethods_thenRetryWhileNotUnique() throws Exception {
|
||||
for (Method method : uuidLongGenerator.getClass().getDeclaredMethods()) {
|
||||
collisionCheck(method);
|
||||
}
|
||||
}
|
||||
|
||||
private void printTableHeader() {
|
||||
logger.info(String.format("%-30s %-15s %-15s", "Approach(method name)", "collisions", "probability"));
|
||||
logger.info("-----------------------------------------------------------------------");
|
||||
}
|
||||
|
||||
private void printOutput(String method, int collisionsCount, double collisionsProbability) {
|
||||
DecimalFormat decimalFormat = new DecimalFormat("#.#####");
|
||||
logger.info(String.format("%-30s %-15s %-15s", method, collisionsCount, decimalFormat.format(collisionsProbability)));
|
||||
}
|
||||
|
||||
private void collisionCheck(Method method) throws Exception {
|
||||
Set<Long> uniqueValues = new HashSet<>();
|
||||
int collisions = 0;
|
||||
for (int i = 0; i < NUMBER_OF_CHECKS; i++) {
|
||||
long uniqueValue = (long) method.invoke(uuidLongGenerator);
|
||||
long uniqueValue;
|
||||
do uniqueValue = (long) method.invoke(uuidLongGenerator); while (!isUnique(uniqueValue));
|
||||
assertThat(uniqueValue).isPositive();
|
||||
if (!uniqueValues.add(uniqueValue)) {
|
||||
collisions++;
|
||||
}
|
||||
}
|
||||
double collisionsProbability = (double) collisions / NUMBER_OF_CHECKS;
|
||||
printOutput(method.getName(), collisions, collisionsProbability);
|
||||
assertThat(collisionsProbability).isLessThan(COLLISION_THRESHOLD);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user