Utwórz GUID w Javie

377

Jakie są najlepsze sposoby utworzenia identyfikatora GUID w Javie?

Chris Dutrow
źródło
3
Pytanie na stackoverflow.com/questions/325443/generate-uuid-in-java dotyczy więcej kolizji GUID, a następnie tego, w jaki sposób odpowiednik GUID znajduje się w stosie technologii Java, co jest (jak sądzę) bardziej w centrum tego pytania.
Jon Adams

Odpowiedzi:

346

Spójrz na klasę UUID dołączoną do Javy 5 i nowszych.

Na przykład:

  • Jeśli chcesz losowego UUID, możesz użyć metody randomUUID .
  • Jeśli chcesz, aby identyfikator UUID był inicjowany na określoną wartość, możesz użyć konstruktora UUID lub metody fromString .
Mark Byers
źródło
7
Jeśli podasz przykład jak Kaleb Brasee, Twoja dobra odpowiedź byłaby jeszcze lepsza.
Zero3
Działa w AndroidStudio 2.3 i co najmniej na poziomie API 21 lub wyższym. Może też z tyłu.
raddevus
5
TL; DR ... "UUID uuid = UUID.randomUUID ();"
Aviram Fireberger
419

java.util.UUID.randomUUID();

Kaleb Brasee
źródło
2
czy to może wrócić powtórzyć? ponieważ Guid nigdy się nie powtórzy
anioł
3
@angel Tak, teoretycznie jest możliwe, aby UUID.randomUUIDmetoda zwróciła duplikat, ale nie jest to wcale realistyczne . Implementacja Oracle / OpenJDK wykorzystuje kryptograficznie silny generator liczb losowych. Biorąc to pod uwagę i biorąc pod uwagę astronomiczny zasięg podany przez tak wiele bitów w UUID, możesz wygenerować wiele milionów takich wartości w swojej aplikacji i nadal dobrze spać. Zastosowanie jednego z pozostałych wariantów dodatkowo zmniejsza możliwość kolizji jeszcze bliżej zera dzięki zastosowaniu „przestrzeni i czasu”, [1] adresu lub nazwy MAC oraz [2] bieżącej daty i godziny, jako ograniczeń.
Basil Bourque,
@RenniePet Eh, jeśli jesteś paranoikiem i podczas tworzenia nowego masz dostęp do listy już używanych identyfikatorów, po prostu generujesz nowe, whiledopóki nie dostaniesz takiego, którego nie ma na liście: p
Nyerguds,
1
Generator losowych liczb kryptograficznych Oracle to zazwyczaj PRNG z losowym ziarnem. Losowe ziarno jest zwykle uzyskiwane przy użyciu źródła „entropii” dostarczonego przez system operacyjny. Jeśli możesz zdegradować lub skompromitować to źródło, wówczas zwiększa się prawdopodobieństwo, że generator liczb losowych kryptograficznych wygeneruje ten sam numer. Warto również zauważyć, że na niektórych (np. Zwirtualizowanych) platformach systemowi operacyjnemu może zabraknąć entropii. Istnieją „podejrzane hacki” do obejścia tego, ale pociągają za sobą pogorszenie jakości entropii.
Stephen C
To nie jest tylko problem akademicki. Widziałem ( niepotwierdzone !! ) twierdzą, że ktoś nie napotkasz problemy z losowych opartego UUID nie jest unikatowy.
Stephen C
31

To zależy, jakiego rodzaju UUID chcesz.

  • Standardowa UUIDklasa Java generuje UUID w wersji 4 (losowy). ( AKTUALIZACJA - Wersja 3 (nazwa) UUID mogą być również generowane.) Może także obsługiwać inne warianty, chociaż nie może ich wygenerować. (W tym przypadku, „uchwyt” oznacza konstrukt UUIDprzypadkach od long, byte[]lub Stringreprezentacji oraz zapewnienie odpowiednich udostępniające).

  • W Java UUID Generator (JUG) objaśnienia wykonawcze do wspierania „wszystkie«oficjalne»3 rodzaje UUID zdefiniowany przez RFC-4122 ” ... choć faktycznie RFC definiuje 4 rodzaje i wymienia 5th typu.

Więcej informacji na temat typów i wariantów UUID można znaleźć w Wikipedii , a krwawe szczegóły w RFC 4122 i innych specyfikacjach.

Stephen C.
źródło
1
Nie do końca prawda, może również generować identyfikatory UUID oparte na nazwie (wersja 3) za pomocąUUID.nameUUIDFromBytes(byte[] name)
DennisK
Poprawiono mnie. Oparłem się na opisie javadoc, który mówi: „Fabryka statyczna do pobierania identyfikatora UUID typu 3 (na podstawie nazwy) w oparciu o określoną tablicę bajtów”
Stephen C
Nie sądzę, żeby post był dokładny. Dokumenty UUID Java stwierdzają, że konstruktor generuje wariant typu 2, a nie losowy. Do użytku typu 3 public static UUID nameUUIDFromBytes(byte[] name). do użytku typu 4 public static UUID randomUUID(). Typ 1 nie jest dostępny z klasą JDK.
slartibartfast
Nie. Myślę, że mam rację. Stan javadocs: „chociaż konstruktory pozwalają na tworzenie dowolnego wariantu UUID (opisanego poniżej)”. i 4 warianty są wymienione poniżej, w tym typ 1. Rzeczywiście, przeczytaj javadoc dlaclockSequence()
Stephen C
27

Aby rozszerzyć odpowiedź Marka Byersa o przykład:

import java.util.UUID;

public class RandomStringUUID {
    public static void main(String[] args) {
        UUID uuid = UUID.randomUUID();
        System.out.println("UUID=" + uuid.toString() );
    }
}
Anton Belev
źródło
6

Pozostałe odpowiedzi są poprawne, szczególnie ten jeden przez Stephen C .

Osiągnięcie poza Javą

Generowanie wartości UUID w Javie jest ograniczone do wersji 4 (losowej) ze względów bezpieczeństwa.

Jeśli chcesz mieć inne wersje identyfikatorów UUID, jedną z możliwości jest uzyskanie dostępu do aplikacji Java poza maszyną JVM w celu generowania identyfikatorów UUID poprzez wywołanie:

  • Narzędzie wiersza polecenia W
    pakiecie z prawie każdym systemem operacyjnym.
    Na przykład uuidgenznaleziono w Mac OS X, BSD i Linux.
  • Serwer bazy danych
    Użyj JDBC, aby pobrać identyfikator UUID wygenerowany na serwerze bazy danych.
    Na przykład uuid-ossprozszerzenie często jest dołączane do Postgres . To rozszerzenie może generować wartości wersji 1, 3 i 4 oraz dodatkowo kilka odmian:
    • uuid_generate_v1mc() - generuje UUID wersji 1, ale używa losowego adresu MAC multiemisji zamiast rzeczywistego adresu MAC komputera.
    • uuid_generate_v5(namespace uuid, name text) - generuje UUID w wersji 5, który działa jak UUID w wersji 3, z tym wyjątkiem, że SHA-1 jest używany jako metoda mieszania.
  • Usługa sieciowa
    Na przykład Generator UUID tworzy wersje 1 i 3, a także wartości zerowe i identyfikator GUID .
Basil Bourque
źródło
3
Mam kilka problemów z twoją odpowiedzią: Po pierwsze, okazało się, że błędem jest to, że możesz pobrać tylko V4 ze standardowej biblioteki Java (V3 jest również możliwe). Po drugie, sprawiasz, że brzmi to tak, jakby poza standardową biblioteką nie było żadnych opcji w Javie, a także machanie ręką „ze względów bezpieczeństwa”. I na koniec, po prostu generalnie nieefektywne (programowo i / lub pod względem wydajności), aby zacząć w zależności od zewnętrznych źródeł, gdy jest wiele sposobów, aby to zrobić w Javie (chyba, że ​​potrzebujesz tego w tych, oczywiście, np. W ramach tworzenia rekord na serwerze SQL).
DennisK,