JAVA-1749 Update UUID article and code

This commit is contained in:
mikr 2020-06-07 12:13:32 +02:00
parent e82a890924
commit 6f21d2eb74
2 changed files with 156 additions and 42 deletions

View File

@ -3,30 +3,57 @@ package com.baeldung.uuid;
import java.io.UnsupportedEncodingException;
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;
public class UUIDGenerator {
/**
* These are predefined UUID for name spaces
*/
private static final String NAMESPACE_DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
private static final String NAMESPACE_URL = "6ba7b811-9dad-11d1-80b4-00c04fd430c8";
private static final String NAMESPACE_OID = "6ba7b812-9dad-11d1-80b4-00c04fd430c8";
private static final String NAMESPACE_X500 = "6ba7b814-9dad-11d1-80b4-00c04fd430c8";
private static final char[] hexArray = "0123456789ABCDEF".toCharArray();
public static void main(String[] args) {
try {
System.out.println("Type 3 : " + generateType3UUID(NAMESPACE_DNS, "google.com"));
System.out.println("Type 4 : " + generateType4UUID());
System.out.println("Type 5 : " + generateType5UUID(NAMESPACE_URL, "google.com"));
System.out.println("Unique key : " + generateUniqueKeysWithUUIDAndMessageDigest());
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
e.printStackTrace();
/**
* Type 1 UUID Generation
*/
public static UUID generateType1UUID() {
long most64SigBits = get64MostSignificantBitsForVersion1();
long least64SigBits = get64LeastSignificantBitsForVersion1();
return new UUID(most64SigBits, least64SigBits);
}
private static long get64LeastSignificantBitsForVersion1() {
Random random = new Random();
long random63BitLong = random.nextLong() & 0x3FFFFFFFFFFFFFFFL;
long variant3BitFlag = 0x8000000000000000L;
return random63BitLong + variant3BitFlag;
}
private static long get64MostSignificantBitsForVersion1() {
LocalDateTime start = LocalDateTime.of(1582, 10, 15, 0, 0, 0);
Duration duration = Duration.between(start, LocalDateTime.now());
long seconds = duration.getSeconds();
long nanos = duration.getNano();
long timeForUuidIn100Nanos = seconds * 10000000 + nanos * 100;
long least12SignificatBitOfTime = (timeForUuidIn100Nanos & 0x000000000000FFFFL) >> 4;
long version = 1 << 12;
return (timeForUuidIn100Nanos & 0xFFFFFFFFFFFF0000L) + version + least12SignificatBitOfTime;
}
/**
* Type 3 UUID Generation
*
* @throws UnsupportedEncodingException
*/
public static UUID generateType3UUID(String namespace, String name) throws UnsupportedEncodingException {
byte[] nameSpaceBytes = bytesFromUUID(namespace);
byte[] nameBytes = name.getBytes("UTF-8");
byte[] result = joinBytes(nameSpaceBytes, nameBytes);
return UUID.nameUUIDFromBytes(result);
}
/**
@ -37,28 +64,18 @@ public class UUIDGenerator {
return uuid;
}
/**
* Type 3 UUID Generation
*
* @throws UnsupportedEncodingException
*/
public static UUID generateType3UUID(String namespace, String name) throws UnsupportedEncodingException {
String source = namespace + name;
byte[] bytes = source.getBytes("UTF-8");
UUID uuid = UUID.nameUUIDFromBytes(bytes);
return uuid;
}
/**
* Type 5 UUID Generation
*
* @throws UnsupportedEncodingException
*/
public static UUID generateType5UUID(String namespace, String name) throws UnsupportedEncodingException {
String source = namespace + name;
byte[] bytes = source.getBytes("UTF-8");
UUID uuid = type5UUIDFromBytes(bytes);
return uuid;
byte[] nameSpaceBytes = bytesFromUUID(namespace);
byte[] nameBytes = name.getBytes("UTF-8");
byte[] result = joinBytes(nameSpaceBytes, nameBytes);
return type5UUIDFromBytes(result);
}
public static UUID type5UUIDFromBytes(byte[] name) {
@ -104,7 +121,7 @@ public class UUIDGenerator {
return digest;
}
public static String bytesToHex(byte[] bytes) {
private static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
@ -114,4 +131,37 @@ public class UUIDGenerator {
return new String(hexChars);
}
private static byte[] bytesFromUUID(String uuidHexString) {
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));
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);
return (byte) ((firstDigit << 4) + secondDigit);
}
public static byte[] joinBytes(byte[] byteArray1, byte[] byteArray2) {
int finalLength = byteArray1.length + byteArray2.length;
byte[] result = new byte[finalLength];
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];
}
return result;
}
}

View File

@ -0,0 +1,64 @@
package com.baeldung.uuid;
import org.junit.jupiter.api.Test;
import java.io.UnsupportedEncodingException;
import java.util.UUID;
import static org.junit.jupiter.api.Assertions.assertEquals;
class UUIDGeneratorUnitTest {
private static final String NAMESPACE_URL = "6ba7b811-9dad-11d1-80b4-00c04fd430c8";
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() {
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 {
UUID uuid = UUIDGenerator.generateType3UUID(NAMESPACE_DNS, "baeldung.com");
assertEquals("23785b78-0132-3ac6-aff6-cfd5be162139", uuid.toString());
assertEquals(3, uuid.version());
assertEquals(2, uuid.variant());
}
@Test
public void version_3_UUID_is_correctly_generated_for_domain_d() throws UnsupportedEncodingException {
UUID uuid = UUIDGenerator.generateType3UUID(NAMESPACE_DNS, "d");
assertEquals("dbd41ecb-f466-33de-b309-1468addfc63b", uuid.toString());
assertEquals(3, uuid.version());
assertEquals(2, uuid.variant());
}
@Test
public void version_4_UUID_is_generated_with_correct_length_version_and_variant() {
UUID uuid = UUIDGenerator.generateType4UUID();
assertEquals(36, uuid.toString().length());
assertEquals(4, uuid.version());
assertEquals(2, uuid.variant());
}
@Test
public void version_5_UUID_is_correctly_generated_for_domain_baeldung_com() throws UnsupportedEncodingException {
UUID uuid = UUIDGenerator.generateType5UUID(NAMESPACE_URL, "baeldung.com");
assertEquals("aeff44a5-8a61-52b6-bcbe-c8e5bd7d0300", uuid.toString());
assertEquals(5, uuid.version());
assertEquals(2, uuid.variant());
}
}