Vejledning til UUID i Java

1. Oversigt

UUID (Universally Unique Identifier), også kendt som GUID (Globally Unique Identifier) ​​repræsenterer en 128-bit lang værdi, der er unik til alle praktiske formål. Standardrepræsentationen af ​​UUID bruger hex cifre (oktetter):

123e4567-e89b-12d3-a456-556642440000

En UUID består af op af hex cifre (4 tegn hver) sammen med 4 "-" symboler, der udgør dens længde svarende til 36 tegn.

Nul UUID er en særlig form for UUID, hvor alle bits er sat til nul.

I denne artikel vil vi se på UUID klasse i Java. Først skal vi se på, hvordan man bruger klassen selv. Derefter ser vi på de forskellige typer UUID'er, og hvordan vi kan generere dem i Java.

2. Den UUID Klasse

UUID-klassen har en enkelt konstruktør:

UUID uuid = nyt UUID (lang mostSignificant64Bits, lang mindstSignificant64Bits);

Hvis vi vil bruge denne konstruktør, skal vi angive to lange værdier. Det kræver dog, at vi selv konstruerer bitmønsteret til UUID.

For nemheds skyld er der tre statiske metoder til at oprette et UUID. Disse er:

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

Denne metode opretter en version 3 UUID fra det givne byte-array.

UUID uuid = UUID.randomUUID (); 

Det randomUUID () metoden opretter en version 4 UUID. Dette er den mest bekvemme måde at oprette et UUID på.

UUID uuid = UUID.fromString (streng uuidHexDigitString); 

Den tredje statiske metode returnerer et UUID-objekt givet strengrepræsentationen af ​​et givet UUID.

Lad os nu se på, hvordan et UUID er struktureret.

3. Struktur

Lad os tage eksemplet UUID:

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

3.1. UUID-variant

EN repræsenterer den variant, der bestemmer layoutet for UUID. Alle andre bits i UUID afhænger af indstillingen af ​​bitene i variantfeltet. Varianten bestemmes af 3 mest betydningsfulde bit A:

 MSB1 MSB2 MSB3 0 X X reserveret (0) 1 0 X nuværende variant (2) 1 1 0 forbeholdt Microsoft (6) 1 1 1 reserveret til fremtid (7)

Værdien af EN i den nævnte UUID er 'a'. Den binære ækvivalent af 'a' (= 10xx) viser varianten som 2.

3.2. UUID-version

B repræsenterer versionen. Versionen i den nævnte UUID (værdi af B) er 4.

Java giver metoder til at hente variant og version af UUID:

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

Disse er 5 forskellige versioner til variant 2 UUID'er: Time Based (UUIDv1), DCE Security (UUIDv2), Name Based (UUIDv3 and UUIDv5), Random (UUIDv4).

Java giver en implementering af v3 og v4, men giver også en konstruktør til generering af enhver type UUID:

UUID uuid = ny UUID (lang mostSigBits, lang mindstSigBits);

4. UUID-versionerne

4.1. Version 1

UUID version 1 er baseret på det aktuelle tidsstempel målt i enheder på 100 nanosekunder fra den 15. oktober 1582 sammenkædet med MAC-adressen på den enhed, hvor UUID oprettes.

Hvis privatliv er et problem, kan UUID version 1 alternativt genereres med et tilfældigt 48-bit nummer i stedet for MAC-adressen.

I denne artikel vil vi dette alternativ. Først genererer vi de 64 mindst og mest betydningsfulde bits som lange værdier:

privat statisk lang get64LeastSignificantBitsForVersion1 () {Tilfældig tilfældig = ny tilfældig (); lang random63BitLong = random.nextLong () & 0x3FFFFFFFFFFFFFFFL; lang variant3BitFlag = 0x8000000000000000L; returnere tilfældigt63BitLong + variant3BitFlag; } privat statisk lang get64MostSignificantBitsForVersion1 () {LocalDateTime start = LocalDateTime.of (1582, 10, 15, 0, 0, 0); Varighed varighed = Varighed. Mellem (start, LocalDateTime.now ()); lange sekunder = duration.getSeconds (); lange nanoer = varighed.getNano (); lang tidForUuidIn100Nanos = sekunder * 10000000 + nanoer * 100; lang mindst12SignificatBitOfTime = (timeForUuidIn100Nanos & 0x000000000000FFFFL) >> 4; lang version = 1 << 12; returnere (timeForUuidIn100Nanos & 0xFFFFFFFFFFFF0000L) + version + mindst12SignificatBitOfTime; }

Vi kan derefter overføre disse to værdier til konstruktøren af ​​UUID:

offentlig statisk UUID createType1UUID () {long most64SigBits = get64MostSignificantBitsForVersion1 (); lang mindst64SigBits = get64LeastSignificantBitsForVersion1 (); returner nyt UUID (most64SigBits, least64SigBits); }

4.2. Version 2

Version 2 er også baseret på et tidsstempel og MAC-adressen. RFC 4122 specificerer dog ikke de nøjagtige genereringsoplysninger, derfor ser vi ikke på en implementering i denne artikel.

4.3. Version 3 & 5

UUID'erne genereres ved hjælp af hash af navneområde og navn. Navneområdets identifikatorer er UUID'er som Domain Name System (DNS), Object Identifiers (OIDs), URL'er osv.

UUID = hash (NAMESPACE_IDENTIFIER + NAVN)

Den eneste forskel mellem UUIDv3 og UUIDv5 er Hashing-algoritmen - v3 bruger MD5 (128 bit), mens v5 bruger SHA-1 (160 bits).

Kort sagt, vi trunkerer den resulterende hash til 128-bit og erstatter derefter 4 bit for versionen og 2 bit for varianten.

Lad os generere type 3 UUID:

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

Her er det vigtigt at bemærke, at hex-strengen til navneområdet først skal konverteres til et byte-array.

Java leverer ikke implementeringen til type 5. Tjek vores kildekodelager for UUIDv5.

4.4. Version 4

UUID v4-implementeringen bruger tilfældige tal som kilde. Java-implementeringen er SecureRandom - der bruger en uforudsigelig værdi som frøet til at generere tilfældige tal for at reducere risikoen for kollisioner.

Lad os generere version 4 UUID:

UUID uuid = UUID.randomUUID ();

Lad os generere en unik nøgle ved hjælp af 'SHA-256' og en tilfældig UUID:

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

5. Konklusion

I denne artikel så vi, hvordan et UUID er struktureret, hvilke varianter og versioner der er. Vi lærte, for hvilke versioner Java giver en out-of-the-box implementering, og kiggede på kodeeksempler for at generere de andre versioner.

Og som altid er implementeringskildekoden tilgængelig på Github.