2008-11-28 12 views

Odpowiedz

207

Według the documentation statyczna metoda UUID.randomUUID() generuje typ 4 UUID.

Oznacza to, że w przypadku niektórych informacji o typie użytych jest sześć bitów, a pozostałe 122 są przydzielane losowo.

Sześć nieliniowych bitów jest rozłożonych czterema w najbardziej znaczącej połowie UUID, a dwie w najmniej znaczącej połowie. Tak więc najważniejsza połowa twojego UUID zawiera 60 bitów losowości, co oznacza, że ​​musisz średnio wygenerować 2^30 identyfikatorów UUID, aby uzyskać kolizję (w porównaniu do 2^61 dla pełnego UUID).

Powiedziałbym więc, że jesteś raczej bezpieczny. Należy jednak zauważyć, że jest to absolutnie nieprawdą w przypadku innych typów UUID, o czym wspomina Carl Seleborg.

Nawiasem mówiąc, lepiej byłoby, gdybyś użył najmniej znaczącej połowy UUID (lub po prostu wygenerował losowo długą używając SecureRandom).

+3

Nie jestem pewien, czy jest to całkowicie poprawne - patrząc na implementację, jasne jest, że informacje o wersji/wariancie nie są przechowywane w najbardziej znaczących bitach, ale raczej gdzieś pośrodku. – Tom

+2

@RasmusFaber Komentarz [Tom] (http://stackoverflow.com/users/223201/tom) jest poprawny: Odpowiedź tutaj jest ** niepoprawna o sześciu najbardziej znaczących bitach ** będących informacją o typie. Istnieje rzeczywiście sześć bitów danych nielosowych, ale cztery bity identyfikują wersję 4, a dwa inne są zarezerwowane.Cztery i dwa bity znajdują się w różnych pozycjach w pobliżu środka 128-bitowej wartości. Zobacz [artykuł Wikipedii] (https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_.28random.29). –

+0

Dzięki @Tom and Basil. Zaktualizowałem odpowiedź. –

10

Lepszym wyjściem jest generowanie losowej długiej wartości, a następnie wszystkie bity są losowe. W Javie 6, nowy losowy() używa System.nanoTime() plus licznik jako nasienie.

Istnieją różne poziomy unikalności.

Jeśli potrzebujesz wyjątkowości na wielu komputerach, możesz mieć centralną tabelę bazy danych do przydzielania niepowtarzalnych identyfikatorów, a nawet partii niepowtarzalnych identyfikatorów.

Jeśli wystarczy mieć unikatowości w jednej aplikacji może po prostu masz licznik (lub licznik, który zaczyna się od currentTimeMillis() * 1000 lub nanoTime() w zależności od potrzeb)

7

Zastosowanie Czas YYYYDDDD (rok + dzień roku) jako prefiks. Zmniejsza to fragmentację bazy danych w tabelach i indeksach. Ta metoda zwraca byte[40]. Używałem go w środowisku hybrydowym, w którym identyfikator SID usługi Active Directory (varbinary(85)) jest kluczem dla użytkowników LDAP, a identyfikator generowany automatycznie dla aplikacji jest używany dla użytkowników innych niż LDAP. Również duża liczba transakcji dziennie w tabelach transakcyjnych (sektor bankowy) nie można używać standardowych Int rodzaje kluczy

private static final DecimalFormat timeFormat4 = new DecimalFormat("0000;0000"); 

public static byte[] getSidWithCalendar() { 
    Calendar cal = Calendar.getInstance(); 
    String val = String.valueOf(cal.get(Calendar.YEAR)); 
    val += timeFormat4.format(cal.get(Calendar.DAY_OF_YEAR)); 
    val += UUID.randomUUID().toString().replaceAll("-", ""); 
    return val.getBytes(); 
} 
+3

Zamiast tego należy użyć standardowego identyfikatora UUID V1? – ShadowChaser

Powiązane problemy