Rozumiem różnice między tymi dwoma dokumentami.
uuid1()
:
Wygeneruj identyfikator UUID na podstawie identyfikatora hosta, numeru sekwencji i bieżącej godziny
uuid4()
:
Wygeneruj losowy UUID.
uuid1
Używa więc informacji o maszynie / sekwencji / czasie do wygenerowania UUID. Jakie są zalety i wady korzystania z nich?
Wiem, że uuid1()
mogą mieć obawy dotyczące prywatności, ponieważ są oparte na informacjach o maszynie. Zastanawiam się, czy jest coś bardziej subtelnego przy wyborze jednego lub drugiego. Właśnie używam uuid4()
teraz, ponieważ jest to całkowicie losowy UUID. Ale zastanawiam się, czy powinienem używać, uuid1
aby zmniejszyć ryzyko kolizji.
Zasadniczo szukam wskazówek ludzi na temat najlepszych praktyk korzystania z jednego kontra drugiego. Dzięki!
Odpowiedzi:
uuid1()
gwarantuje, że nie spowoduje żadnych kolizji (przy założeniu, że nie tworzysz ich zbyt wielu jednocześnie). Nie użyłbym go, jeśli ważne jest, aby nie istniało połączenie międzyuuid
komputerem a komputerem, ponieważ adres mac przyzwyczaja się do tego, aby był unikalny na różnych komputerach.Możesz utworzyć duplikaty, tworząc więcej niż 2 14 uuid1 w czasie krótszym niż 100ns, ale nie jest to problem w większości przypadków użycia.
uuid4()
generuje, jak powiedziałeś, losowy UUID. Szansa na kolizję jest naprawdę bardzo mała. Na tyle mały, że nie powinieneś się tym martwić. Problem polega na tym, że zły generator liczb losowych zwiększa prawdopodobieństwo kolizji.Ta doskonała odpowiedź Boba Amana ładnie podsumowuje. (Polecam przeczytać całą odpowiedź).
źródło
uuid1
niekoniecznie będzie produkować unikalne UUID, jeśli produkujesz kilka na sekundę w tym samym węźle. Przykład:[uuid.uuid1() for i in range(2)]
. Chyba że dzieje się coś dziwnego, czego mi brakuje.uuid1
ma numer sekwencyjny (czwarty element w twoim przykładzie), więc jeśli nie wykorzystasz wszystkich bitów licznika, nie dojdzie do kolizji.Jednym z przykładów, w którym można rozważyć
uuid1()
,uuid4()
jest przypadek, gdy UUID są tworzone na osobnych komputerach , na przykład gdy wiele transakcji online jest przetwarzanych na kilku komputerach w celu skalowania.W takiej sytuacji ryzyko kolizji z powodu złych wyborów w sposobie inicjowania generatorów liczb pseudolosowych, na przykład, a także potencjalnie większa liczba wyprodukowanych identyfikatorów UUID, zwiększa prawdopodobieństwo utworzenia duplikatów identyfikatorów.
Innym zainteresowaniem
uuid1()
w tym przypadku jest to, że maszyna, na której każdy identyfikator GUID został początkowo utworzony, jest domyślnie rejestrowana (w części UUID dotyczącej „węzła”). To i informacje o czasie mogą pomóc choćby w debugowaniu.źródło
Mój zespół po prostu miał problemy z użyciem UUID1 do skryptu aktualizacji bazy danych, w którym wygenerowaliśmy ~ 120 000 UUID w ciągu kilku minut. Kolizja UUID doprowadziła do naruszenia ograniczenia klucza podstawowego.
Uaktualniliśmy setki serwerów, ale w naszych instancjach Amazon EC2 napotkaliśmy ten problem kilka razy. Podejrzewam, że niska rozdzielczość zegara i przejście na UUID4 rozwiązało to za nas.
źródło
Należy zwrócić uwagę na jedną rzecz
uuid1
, jeśli używasz domyślnego wywołania (bez podaniaclock_seq
parametru), masz szansę na zderzenie: masz tylko 14 bitów losowości (wygenerowanie 18 wpisów w ciągu 100ns daje z grubsza 1% szansy na kolizję zobacz paradoks / atak urodzinowy). Problem nigdy nie wystąpi w większości przypadków użycia, ale na maszynie wirtualnej ze słabą rozdzielczością zegara cię ugryzie.źródło
clock_seq
....Być może coś, o czym nie wspomniano, dotyczy lokalności.
Adres MAC lub kolejność na podstawie czasu (UUID1) może pozwolić na zwiększenie wydajności bazy danych, ponieważ mniejszą ilością pracy jest sortowanie liczb bliżej siebie niż liczb losowych (UUID4) (patrz tutaj ).
Drugim powiązanym problemem jest to, że używanie UUID1 może być przydatne w debugowaniu, nawet jeśli dane źródłowe zostaną utracone lub nie zostaną wyraźnie zapisane (jest to oczywiście sprzeczne z kwestią prywatności wspomnianą przez PO).
źródło
Oprócz zaakceptowanej odpowiedzi istnieje trzecia opcja, która może być przydatna w niektórych przypadkach:
v1 z losowym MAC („v1mc”)
Możesz stworzyć hybrydę między wersją v1 i v4, celowo generując identyfikatory UUID v1 z losowym adresem MAC emisji (jest to dozwolone w specyfikacji v1). Wynikowy identyfikator UUID v1 jest zależny od czasu (jak zwykły v1), ale brakuje mu wszystkich informacji specyficznych dla hosta (jak v4). Jest również znacznie bliższy v4 pod względem odporności na zderzenia: v1mc = 60 bitów czasu + 61 losowych bitów = 121 unikalnych bitów; v4 = 122 losowe bity.
Pierwsze miejsce, w którym się z tym spotkałem, to funkcja uuid_generate_v1mc () Postgresa . Od tego czasu użyłem następującego odpowiednika Pythona:
(uwaga: mam dłuższą + szybszą wersję, która bezpośrednio tworzy obiekt UUID; może publikować, jeśli ktoś chce)
W przypadku DUŻYCH ilości połączeń / sekundę może to potencjalnie wyczerpać losowość systemu. Państwo mogli skorzystać z stdlib
random
zamiast modułu (prawdopodobnie będzie to również szybciej). Ale UWAGA: potrzeba tylko kilkuset UUID, aby atakujący mógł określić stan RNG, a tym samym częściowo przewidzieć przyszłe UUID.źródło