Sprievodca po UUID v Jave

1. Prehľad

UUID (univerzálny jedinečný identifikátor), tiež známy ako GUID (globálne jedinečný identifikátor), predstavuje 128-bitová hodnota, ktorá je jedinečná pre všetky praktické účely. Štandardné znázornenie UUID používa hexadecimálne číslice (oktety):

123e4567-e89b-12d3-a456-556642440000

UUID sa skladá z hexadecimálnych číslic (každé 4 znaky) spolu so 4 znakmi „-“, ktoré ho tvoria dĺžka rovná 36 znakom.

Nil UUID je špeciálna forma UUID, v ktorej sú všetky bity nastavené na nulu.

V tomto článku sa pozrieme na UUID triedy v Jave. Najprv sa pozrieme na to, ako používať samotnú triedu. Potom sa pozrieme na rôzne typy UUID a na to, ako ich môžeme generovať v Jave.

2. The UUID Trieda

Trieda UUID má jediný konštruktor:

UUID uuid = nový UUID (dlhý mostSignificant64Bits, dlhý najmenejSignificant64Bits);

Ak chceme použiť tento konštruktor, musíme uviesť dve dlhé hodnoty. Vyžaduje si to však od nás, aby sme si sami vytvorili bitový vzor pre UUID.

Pre uľahčenie existujú tri statické metódy na vytvorenie UUID. Sú to:

UUID uuid = UUID.nameUUIDFromBytes (byte [] bajtov); 

Táto metóda vytvorí z daného bajtového poľa UUID verzie 3.

UUID uuid = UUID.randomUUID (); 

The randomUUID () metóda vytvorí UUID verzie 4. Toto je najpohodlnejší spôsob vytvárania UUID.

UUID uuid = UUID.fromString (reťazec uuidHexDigitString); 

Tretia statická metóda vracia objekt UUID daný reťazcovou reprezentáciou daného UUID.

Poďme sa teraz pozrieť na to, ako je štruktúrovaný UUID.

3. Štruktúra

Zoberme si príklad UUID:

123e4567-e89b-42d3-a456-556642440000 xxxxxxxx-xxxx-Bxxx-Axxx-xxxxxxxxxxxxxx

3.1. Variant UUID

A predstavuje variant, ktorý určuje rozloženie UUID. Všetky ostatné bity v UUID závisia od nastavenia bitov v poli variant. Variant je určený 3 najvýznamnejšími bitmi A:

 MSB1 MSB2 MSB3 0 X X vyhradené (0) 1 0 X aktuálny variant (2) 1 1 0 vyhradené pre Microsoft (6) 1 1 1 vyhradené pre budúcnosť (7)

Hodnota A v uvedenom UUID je ‘a‘. Binárny ekvivalent ‘a’ (= 10xx) zobrazuje variant ako 2.

3.2. Verzia UUID

B predstavuje verziu. Verzia v uvedenom UUID (hodnota B) je 4.

Java poskytuje metódy na získanie variantu a verzie UUID:

UUID uuid = UUID.randomUUID (); int variant = uuid.variant (); int verzia = uuid.version ();

Toto je 5 rôznych verzií pre variant 2 UUID: Časovo založené (UUIDv1), Zabezpečenie DCE (UUIDv2), Na základe názvu (UUIDv3 a UUIDv5), Náhodné (UUIDv4).

Java poskytuje implementáciu pre v3 a v4, ale tiež poskytuje konštruktér na generovanie ľubovoľného typu UUID:

UUID uuid = nový UUID (dlhý mostSigBits, dlhý najmenejSigBits);

4. Verzie UUID

4.1. Verzia 1

UUID verzia 1 je založená na aktuálnej časovej značke meranej v jednotkách 100 nanosekúnd od 15. októbra 1582, zreťazenej s MAC adresou zariadenia, kde je UUID vytvorený.

Ak je problémom súkromie, UUID verzie 1 je možné alternatívne vygenerovať pomocou náhodného 48-bitového čísla namiesto adresy MAC.

V tomto článku uvedieme túto alternatívu. Najskôr vygenerujeme 64 najmenších a najvýznamnejších bitov ako dlhé hodnoty:

private static long get64LeastSignificantBitsForVersion1 () {Random random = new Random (); long random63BitLong = random.nextLong () & 0x3FFFFFFFFFFFFFFFL; dlhý variant3BitFlag = 0x8000000000000000L; návrat random63BitLong + variant3BitFlag; } private static long get64MostSignificantBitsForVersion1 () {LocalDateTime start = LocalDateTime.of (1582, 10, 15, 0, 0, 0); Duration duration = Duration.b Between (start, LocalDateTime.now ()); dlhé sekundy = duration.getSeconds (); long nanos = duration.getNano (); long timeForUuidIn100Nanos = sekundy * 10 000 000 + nanos * 100; long najmenej12SignificatBitOfTime = (timeForUuidIn100Nanos & 0x000000000000FFFFL) >> 4; dlhá verzia = 1 << 12; návrat (timeForUuidIn100Nanos & 0xFFFFFFFFFFFF0000L) + verzia + najmenej12SignificatBitOfTime; }

Potom môžeme tieto dve hodnoty odovzdať konštruktoru UUID:

public static UUID generateType1UUID () {long most64SigBits = get64MostSignificantBitsForVersion1 (); long najmenej64SigBits = get64LeastSignificantBitsForVersion1 (); vrátiť nové UUID (most64SigBits, najmenej64SigBits); }

4.2. Verzia 2

Verzia 2 je založená na časovej značke a MAC adrese. RFC 4122 však nešpecifikuje presné podrobnosti generovania, preto sa v tomto článku nebudeme zaoberať implementáciou.

4.3. Verzia 3 a 5

UUID sa generujú pomocou hash menného priestoru a názvu. Identifikátory menného priestoru sú UUID, ako je Domain Name System (DNS), identifikátory objektov (OID), URL atď.

UUID = hash (NAMESPACE_IDENTIFIER + NAME)

Jediným rozdielom medzi UUIDv3 a UUIDv5 je hashingový algoritmus - v3 používa MD5 (128 bitov), ​​zatiaľ čo v5 používa SHA-1 (160 bitov).

Zjednodušene povedané, výsledný hash skrátime na 128 bitov a potom nahradíme 4 bitové verzie a 2 bitové varianty.

Vygenerujme UUID typu 3:

byte [] nameSpaceBytes = bytesFromUUID (namespace); byte [] nameBytes = name.getBytes ("UTF-8"); byte [] výsledok = joinBytes (nameSpaceBytes, nameBytes); UUID uuid = UUID.nameUUIDFromBytes (výsledok);

Tu je dôležité si uvedomiť, že šesťuholníkový reťazec pre priestor mien je potrebné najskôr previesť na bajtové pole.

Java neposkytuje implementáciu pre typ 5. Skontrolujte UUIDv5 v našom úložisku zdrojových kódov.

4.4. Verzia 4

Implementácia UUID v4 používa ako zdroj náhodné čísla. Implementácia Java je SecureRandom - ktorý používa ako semeno nepredvídateľnú hodnotu na generovanie náhodných čísel, aby sa znížila pravdepodobnosť kolízie.

Vygenerujme UUID verzie 4:

UUID uuid = UUID.randomUUID ();

Vytvorme jedinečný kľúč pomocou kľúča „SHA-256“ a náhodného UUID:

MessageDigest salt = MessageDigest.getInstance ("SHA-256"); salt.update (UUID.randomUUID (). toString (). getBytes ("UTF-8")); String digest = bytesToHex (salt.digest ());

5. Záver

V tomto článku sme videli, ako je štruktúrovaný UUID, ktoré varianty a verzie existujú. Dozvedeli sme sa, pre ktoré verzie Java poskytuje out-of-the-box implementáciu, a pozreli sme sa na príklady kódu na vygenerovanie ďalších verzií.

A ako vždy, zdrojový kód implementácie je k dispozícii na stránkach Github.


$config[zx-auto] not found$config[zx-overlay] not found