1 Nisan 2019 Pazartesi

UUID Sınıfı - Version 4 Kullanır - Random Number

Giriş
Şu satırı dahil ederiz.
import java.util.UUID;
Formatı
UUID 8-4-4-4-12 formatında hexadecimal sayılardır.

Bu sınıf Java 5'ten beri var. Açıklaması şöyle. 128 bit yani 16 byte bir değer'dir. UUID'ler de bir çeşit random sayı üreteci sayılabilir.
In its canonical textual representation, the sixteen octets of a UUID are represented as 32 hexadecimal (base 16) digits, displayed in five groups separated by hyphens, in the form 8-4-4-4-12 for a total of 36 characters (32 alphanumeric characters and four hyphens).
Kalıtım Hiyerarşisi
Şöyledir.
public final class UUID
  extends Object
  implements Serializable, Comparable<UUID>
UUID Standartları
5 çeşit UUID standardı var. Bunlardan 4 tanesi şöyle.
Version 1 (date-time and MAC address)
Version 2 (date-time and MAC address, DCE security version)
Versions 3 and 5 (namespace name-based)
Version 4 (random)
Bir başka açıklama şöyle
There are four versions of UUIDs.
- UUID1 uses MAC address and timestamp to generate effective uniqueness.
- UUID3 and UUID5 uses cryptographic hashing and application-provided text strings to generate UUID. (UUID 3 uses MD5 hashing, and UUID 5 uses SHA-1 hashing).
- UUID4 uses pseudo-random number generators to generate UUID.
 time-based UUID Nedir - Version 1 ve 2
Açıklaması şöyle
There are officially 5 types of UUID values, version 1 to 5, but the most common are: time-based (version 1 or version 2) and purely random (version 3). 

The time-based UUIDs encode the number of 10ns since January 1st, 1970 in 7.5 bytes (60 bits), which is split in a “time-low”-“time-mid”-“time-hi” fashion. The missing 4 bits is the version number used as a prefix to the time-hi field.  This yields the 64 bits of the first 3 groups. The last 2 groups are the clock sequence, a value incremented every time the clock is modified and a host unique identifier. Most of the time, the MAC address of the main network interface of the host is used as a unique identifier.
random UUID Nedir - Version 4
Açıklaması şöyle. Yani toplam 128 bit. Bunun 122'biti rastgele üretiliyor.
UUID version 4 identifiers rely on a cryptographically-secure pseudo-random number generator to produce a unique value with extremely high probability across space and time. The version 4 spec defines a 128-bit number comprised of 122 random bits, along with 4 pre-defined version bits labeled ‘0100’ in the identifier standard. The remaining structure includes variant field bits along with a predefined layout for 8 hexadecimal groupings interspersed with dashes, totaling 36 characters when stringified (e.g. df6fdea1–10c3–474c–ae62–e63def80de0b). This structure coupled with the sheer probability space of 2¹²² potential values, means version 4 UUIDs can be produced independently without coordination and still practically guarantee uniqueness.


UUID Sınıfı  Neden Comparable
Java Version 4'ü kullanıyor. Bu aynı zamanda RFC 4122 olarak ta biliniyor. Bu RFC order olmasını istiyor. Dolayısıyla bu sınıf Comparable arayüzünü gerçekleştiriyor.


fromString metodu
Bu metodun yavaşlığıyla ilgili bir yazı burada
toString () çağrısının sonucunu parse eder. Metodun içi şöyle. UUID 5 parçadan oluşmalı.
public static UUID fromString(String name) {
  String[] components = name.split("-");
  if (components.length != 5)
    throw new IllegalArgumentException("Invalid UUID string: "+name);
  for (int i=0; i<5; i++)
    components[i] = "0x"+components[i];

  long mostSigBits = Long.decode(components[0]).longValue();
  mostSigBits <<= 16;
  mostSigBits |= Long.decode(components[1]).longValue();
  mostSigBits <<= 16;
  mostSigBits |= Long.decode(components[2]).longValue();

  long leastSigBits = Long.decode(components[3]).longValue();
  leastSigBits <<= 48;
  leastSigBits |= Long.decode(components[4]).longValue();

  return new UUID(mostSigBits, leastSigBits);
}
Örnek
Şöyle yaparız.
UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
Örnek
Şöyle yaparız.
// Create a fixed UUID:
String uuidString = "D00077B4-EBFB-4BD8-9E3F-1F3943CBCE35";
UUID uuid2 = UUID.fromString(uuidString);
Örnek
Sağdan itibaren 32 karakteri okur. Geri kalanı dikkate almaz. Dolayısıyla şu iki UUID eşit değere sahip olurlar.
public static void main(String[] args) {
  try {
    UUID t1 = UUID.fromString("38e1036d-7527-42a3-98ca-f2f19d3155db");
    UUID t2 = UUID.fromString("123438e1036d-7527-42a3-98ca-f2f19d3155db");
    System.out.println(t1.toString().equals(t2.toString()));
  } catch (Exception e) {
    e.printStackTrace();
  }
}
getMostSignificantBits metodu
Şöyle yaparız.
long a=uuid.getMostSignificantBits(),
long b=uuid.getLeastSignificantBits()
randomUUID metodu
Kodu şöyle
public static UUID  [More ...] randomUUID() {
  SecureRandom ng = numberGenerator;
  if (ng == null) {
    numberGenerator = ng = new SecureRandom();
  }
  byte[] randomBytes = new byte[16];
  ng.nextBytes(randomBytes);
  randomBytes[6]  &= 0x0f;  /* clear version        */
  randomBytes[6]  |= 0x40;  /* set to version 4     */
  randomBytes[8]  &= 0x3f;  /* clear variant        */
  randomBytes[8]  |= 0x80;  /* set to IETF variant  */
  return new UUID(randomBytes);
}
Açıklaması şöyle
java.util.UUID#randomUUID() API internally uses ‘entropy‘ in the operating system to generate a unique number. What does ‘entropy’ mean? The Linux kernel uses certain techniques like a user’s mouse movements, variance in the hardware fan noise, variance in the noise of the device drivers, etc. to generate random numbers. When there is a lack of ‘entropy’ in the operating system, then random number generation will slow down. When there is a slowdown, application threads that are calling this ‘java.util.UUID#randomUUID()’ API call will be put in a BLOCKED state, and they wouldn’t be able to progress further.

If your application uses ‘java.util.UUID#randomUUID()’ API in a critical code path and there is a lack of entropy in the operating system, then multiple threads can enter into this BLOCKED state, bringing your entire application to a grinding halt.
Yani kullanırken dikkatli olmak lazım. Çok fazla thread'in aynı anda bu metodu çağırması entropy'nin bitmesine sebep oluyor. Açıklaması şöyle
Unix-like operating systems come up with special file ‘/dev/random’ that serve as pseudorandom number generators. Java uses this file to generate random numbers. You can configure it to use ‘/dev/urandom’ instead of ‘/dev/random’. 

‘/dev/urandom’ is another special file that is capable of generating random numbers. However, it has the downside of reduced security due to less randomness. You can achieve it by passing the following JVM argument to your application during startup:

-Djava.security.egd=file:/dev/./urandom

Şöyle yaparız.
// Create a random UUID:
UUID uuid = UUID.randomUUID();
Şöyle yaparız.
String userID = UUID.randomUUID().toString();
toString metodu
Gösterim şekli şöyle.
UUID                   = <time_low> "-" <time_mid> "-"
                      <time_high_and_version> "-"
                      <variant_and_sequence> "-"
                      <node>
time_low               = 4*<hexOctet>
time_mid               = 2*<hexOctet>
time_high_and_version  = 2*<hexOctet>
variant_and_sequence   = 2*<hexOctet>
node                   = 6*<hexOctet>
Bir UUID 36 karakter uzunluğundadır. Geleneksel gösteriminde 8-4-4-4-12 şeklinde gruplanır. 32 alfanümerik karaketer + 4 tane çizgi ile toplam 36 karakter eder. UUID şöyledir.
D00077B4-EBFB-4BD8-9E3F-1F3943CBCE35
Her alfanümerik karakter 0x0 - 0xF (4 bit) arasında bir rakamdır.

Örnek
Şöyle yaparız.
UUID uuid = ...;
String s = uuid.toString();
version metodu
Şöyle yaparız
UUID uuid = UUID.randomUUID();
System.out.println(uuid.version());//4
System.out.println(uuid.variant());//2
Diğer
Windows'ta UUID yerine GUID (Globally Unique Identifier) kelimesi kullanılıyor. 

Üretim
UUID çok hızlı üretilirse küçük bir olasılıkla da olsa çakışma olabilir yani aynı değer elde edilebilir.


Hiç yorum yok:

Yorum Gönder