Czy możemy polegać na uuid jako unikalnym identyfikatorze
i np. wykorzystać ten typ jako primary key? Ewentualnie wykorzystać
do zachowania kontraktu equals/hashcode przez cały cykl życia encji?
Czy powinniśmy się martwić tym, że istnieje szansa na duplikaty?
- Jest bezpieczny, o ile bo np. nie obcinasz gdzieś
- Szansa na duplikat jest 1/(2^128) a to jest niewyobrażalnie mało
- UUID ma w sobie też komponent czasowy, co sprawia ze szansa kolizji jest jeszcze mniej realistyczna
Hmm, dobrze zrobiony uuid ma pewnie mniejsze ryzyko niż promieniowanie kosmiczne https://en.wikipedia.org/wiki/Cosmic_ray#Effect_on_electronics ale nie zawsze uuidy są konstruowane w solidny sposób.
Ryzyko kolizji można sprawdzić w tabelce tutaj: https://en.wikipedia.org/wiki/Birthday_problem#Probability_table (aczkolwiek w uuidzie część bitów jest stała, np. bity określające typ uuida, więc trzeba przeskalować liczby z tabelki trochę).
Z tego co pamietam było trafienie na FB GL. Ktoś dostał cudzy UUID do sesji i wbił na nieswoje konto. Ale to jedyny przypadek o jakim słyszałem
UPDATE a jednak GL Przypadkiem wszedł na konto innego użytkownika w GoldenLine, czyli kolizja klucza sesyjnego w praktyce
UPDATE 2 artykuł opisuje jednak drugi przypadek
lookacode1 napisał(a):
Czy możemy polegać na uuid jako unikalnym identyfikatorze
i np. wykorzystać ten typ jako primary key? Ewentualnie wykorzystać
Tak, w zależności od wersji masz zerowe, lub bardzo niskie prawdopodobieństwo kolizji
do zachowania kontraktu equals/hashcode przez cały cykl życia encji?
Nie, bo:
- UUID to 128b a hash zwraca int, czyli 32b wycinanie kawałka z wygenerowanego UUID drastycznie pogorszy szanse na zachowanie jego unikalności
- Dwa obiekty tożsame wg. equals powinny mieć takiego samego hash'a, jak stworzysz 2 obiekty z takimi samymi danymi i wylosujesz sobie wewnątrz hash'a, to zrobi się zabawnie.
Czy powinniśmy się martwić tym, że istnieje szansa na duplikaty?
W wersjach 1, 2 NIE MA takiej możliwości (kiedyś to było), są tworzone na podstawie MAC adresu i timestampa. W Javie klasa UUID pozwala ci generować identyfikatory w ramach namespace (v3) i losowe (v4). W normalnych zastosowaniach, niezależnie od użytej wersji szanse na kolizję są pomijalne w większości zastosowań.
Dwa obiekty tożsame wg. equals powinny mieć takiego samego hash'a, jak stworzysz 2 obiekty z takimi samymi danymi i wylosujesz sobie wewnątrz hash'a, to zrobi się zabawnie.
Dlaczego zabawnie? Po prostu żadne dwa obiekty nie będą równe z punktu widzenia equals/hashcode bo porównywanie w equals opierałoby się
głównie na porównywaniu tego uuid. I to jest de facto pożądany efekt w przypadku encji, która reprezentuje jakiś rekord w bazie i każdy rekord jest inny i nie mogą być sobie równe.
@Shalom
Jest bezpieczny, o ile bo np. nie obcinasz gdzieś
Szansa na duplikat jest 1/(2^128) a to jest niewyobrażalnie mało
UUID ma w sobie też komponent czasowy, co sprawia ze szansa kolizji jest jeszcze mniej realistyczna
Zakładam, że aby doszło do sytuacji, w której aplikacja wygenerowałaby 2 takie same uuid'y musiałoby to się zdarzyć
dokładnie w tym samym czasie i z tej samej instancji aplikacji?
Czy jest sens np. generować 2 uuid'y i je sklejać dla większej pewności w aplikacji gdzie wymagany jest wysoki poziom bezpieczeństwa?
Załóżmy, że używamy uuid jako wartości identyfikatora sesji. Do tego mamy w aplikacji kilka miliardów użytkowników czyli
kilka miliardów identyfikatorów sesji. Czy losując sobie taki identyfikator sesji nie byłoby zagrożenia, że kiedyś trafię i przejmę kogoś sesje?
Wiem, że prawdopodobieństwo i tak jest małe ale pytanie czy powinniśmy je ignorować projektując aplikację?
kilka miliardów
2^128 to jest 340282366920938463463374607431768211456 czyli 34028236692093846346337460743 razy więcej niż 10 miliardów.
Czy możemy polegać na uuid jako unikalnym identyfikatorze?
Tak
Zarejestruj się i dołącz do największej społeczności programistów w Polsce.
Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.