Nazwy i przestrzeni nazw można użyć do stworzenia hierarchii (prawdopodobnie) unikalnych identyfikatorów UUID.
Z grubsza rzecz biorąc, identyfikator UUID typu 3 lub 5 jest generowany przez połączenie identyfikatora przestrzeni nazw z nazwą. Identyfikatory UUID typu 3 używają MD5, a identyfikatory UUID typu 5 używają SHA1. Dostępnych jest tylko 128 bitów, a 5 bitów jest używanych do określenia typu, więc wszystkie bity mieszania nie trafiają do UUID. (Również MD5 jest uważane za zepsute kryptograficznie, a SHA1 jest na ostatnich nogach, więc nie używaj tego do weryfikacji danych, które muszą być „bardzo bezpieczne”). To powiedziawszy, daje ci sposób na stworzenie powtarzalnej / weryfikowalnej funkcji "hash" mapującej możliwie hierarchiczną nazwę na probabilistycznie unikalną 128-bitową wartość, potencjalnie działającą jak hierarchiczny hash lub MAC.
Załóżmy, że masz magazyn (klucz, wartość), ale obsługuje on tylko jedną przestrzeń nazw. Można wygenerować dużą liczbę różnych logicznych przestrzeni nazw przy użyciu identyfikatorów UUID typu 3 lub 5. Najpierw utwórz główny UUID dla każdej przestrzeni nazw. Może to być identyfikator UUID typu 1 (host + znacznik czasu) lub 4 (losowy), pod warunkiem, że gdzieś go przechowujesz. Alternatywnie możesz utworzyć jeden losowy UUID dla swojego roota (lub użyć null
UUID: 00000000-0000-0000-0000-000000000000
as root), a następnie utworzyć odtwarzalny UUID dla każdej przestrzeni nazw używając " uuid -v5 $ROOTUUID $NAMESPACENAME
". Teraz możesz tworzyć unikalne identyfikatory UUID dla kluczy w przestrzeni nazw za pomocą „uuid -v5 $NAMESPACEUUID $KEY
Te identyfikatory UUID można wrzucić do pojedynczego magazynu klucz-wartość z dużym prawdopodobieństwem uniknięcia kolizji. Proces ten można powtarzać rekurencyjnie, tak aby na przykład „wartość” skojarzona z kluczem UUID reprezentowała z kolei pewien rodzaj logicznej „przestrzeni nazw” „jak zasobnik, kontener lub katalog, wówczas jego UUID może być z kolei użyty do generowania bardziej hierarchicznych identyfikatorów UUID.
Wygenerowany identyfikator UUID typu 3 lub 5 zawiera (częściowy) skrót identyfikatora przestrzeni nazw i nazwy w przestrzeni nazw (klucz). Nie więcej przechowuje UUID przestrzeni nazw, niż wiadomość MAC przechowuje zawartość wiadomości, z której jest zakodowana. Z punktu widzenia algorytmu uuid nazwa jest „dowolnym” (oktetowym) ciągiem znaków. Jednak jego znaczenie zależy od aplikacji. Może to być nazwa pliku w katalogu logicznym, identyfikator obiektu w składnicy obiektów itp.
Chociaż działa to dobrze w przypadku umiarkowanie dużej liczby przestrzeni nazw i kluczy, w końcu wyczerpuje się, jeśli dążysz do bardzo dużej liczby unikalnych kluczy z bardzo dużym prawdopodobieństwem. Wpis Wikipedii dotyczący problemu urodzinowego (inaczej Paradoks urodzin) zawiera tabelę, która podaje prawdopodobieństwo co najmniej jednej kolizji dla różnych numerów kluczy i rozmiarów tabel. Dla 128-bitów, haszowanie 26 miliardów kluczy w ten sposób ma prawdopodobieństwo kolizji p=10^-18
(pomijalne), ale 26 bilionów kluczy zwiększa prawdopodobieństwo co najmniej jednej kolizji do p=10^-12
(jeden na bilion), a haszowanie 26*10^15
kluczy zwiększa prawdopodobieństwo co najmniej jedno zderzenie zp=10^-6
(jeden na milion). Dostosowując się do 5 bitów kodujących typ UUID, skończy się nieco szybciej, więc bilion kluczy ma mniej więcej 1 na bilion szans na pojedynczą kolizję.
Zobacz http://en.wikipedia.org/wiki/Birthday_problem#Probability_table, aby zapoznać się z tabelą prawdopodobieństwa.
Więcej informacji na temat kodowania UUID można znaleźć pod adresem http://www.ietf.org/rfc/rfc4122.txt .
Identyfikatory UUID typu 3 i 5 to tylko technika umieszczania skrótu w identyfikatorze UUID.
Skrót SHA1 generuje 160 bitów (20 bajtów); wynik skrótu jest konwertowany na UUID.
Z 20-bajtowym hashem z SHA1:
(Zauważ, że pierwsze dwa bity „9” mają już odpowiednio 1 i 0, więc nie ma to żadnego wpływu).
Co mam haszować?
Pewnie się zastanawiasz, co mam haszować. Zasadniczo haszujesz konkatenację:
Przedrostek ciągu z tak zwaną przestrzenią nazw, aby zapobiec konfliktom nazw.
UUID RFC wstępnie definiuje cztery obszary nazw dla Ciebie:
NameSpace_DNS
: {6ba7b810-9dad-11d1-80b4-00c04fd430c8}NameSpace_URL
: {6ba7b811-9dad-11d1-80b4-00c04fd430c8}NameSpace_OID
: {6ba7b812-9dad-11d1-80b4-00c04fd430c8}NameSpace_X500
: {6ba7b814-9dad-11d1-80b4-00c04fd430c8}Więc możesz razem mieszać:
Następnie dokument RFC definiuje, jak:
Podstawowym celem jest pobranie tylko pierwszych 128 bitów, umieszczenie a
5
w rekordzie typu , a następnie ustawienie pierwszych dwóch bitówclock_seq_hi_and_reserved
sekcji odpowiednio na 1 i 0.Więcej przykładów
Teraz, gdy masz funkcję, która generuje tak zwaną Nazwę , możesz mieć funkcję (w pseudokodzie):
(Zauważ, że endian -ness twojego systemu może wpływać na indeksy powyższych bajtów)
Możesz mieć telefony:
Wróćmy teraz do twojego pytania
Przestrzeń nazw ma dowolny UUID. Może to być jeden z predefiniowanych lub możesz stworzyć własny, np .:
Nazwa to po prostu tekst, który chcesz dołączyć do przestrzeni nazw, a następnie zaszyfrować i wstawić do UUID:
źródło
Namespace_RectalForeignExtractedObject
, zrobiłbym to.Nazwa to nic innego jak identyfikator, który jest unikalny w obrębie jakiejś przestrzeni nazw. Problem polega na tym, że przestrzenie nazw są często dość małe, a nazwy w jednej często kolidują z nazwami w innych. Na przykład numer rejestracyjny mojego samochodu (nazwa) jest unikalny w przestrzeni nazw DMV mojego stanu, ale prawdopodobnie nie jest unikalny na świecie; inne stanowe DMV mogły używać tej samej nazwy we własnych przestrzeniach nazw. Heck, ktoś inny może mieć numer telefonu (imię i nazwisko), który również pasuje, ponieważ jest to kolejna przestrzeń nazw itp.
Identyfikatory UUID można postrzegać jako zamieszkujące pojedynczą przestrzeń nazw tak rozległą, że może zapewnić unikalną nazwę dla wszystkiego ; to właśnie oznacza „uniwersalny”. Ale jak odwzorować istniejące nazwy w innych przestrzeniach nazw na identyfikator UUID?
Jednym z oczywistych rozwiązań jest wygenerowanie UUID (V1 lub V4) dla każdego elementu w celu zastąpienia starych nazw w ich rozłącznych przestrzeniach nazw. Wadą jest to, że są dużo większe, musisz przekazać wszystkie nowe nazwy każdemu, kto ma kopię twojego zbioru danych, zaktualizować wszystkie twoje API itp. Szanse są takie, że nie możesz całkowicie pozbyć się starych nazw w każdym razie, co oznacza, że teraz każdy przedmiot ma dwie nazwy, więc czy poprawiłeś sytuację?
Tutaj właśnie wkraczają V3 / V5. Identyfikatory UUID wyglądają tak samo losowo jak V4, ale w rzeczywistości są deterministyczne; każdy, kto ma odpowiedni identyfikator UUID dla przestrzeni nazw, może następnie niezależnie wygenerować ten sam identyfikator UUID dla dowolnej nazwy w tej przestrzeni nazw. Nie musisz ich w ogóle publikować ani nawet wstępnie generować, ponieważ każdy może je tworzyć w locie w razie potrzeby!
Nazwy DNS i adresy URL są bardzo często używanymi przestrzeniami nazw, dlatego opublikowano dla nich standardowe identyfikatory UUID; Nazwy ASN.1 OID i X.500 nie są tak powszechne, ale organizacje normalizacyjne je uwielbiają, więc opublikowały również dla nich standardowe identyfikatory UUID przestrzeni nazw.
W przypadku wszystkich innych przestrzeni nazw musisz wygenerować własny identyfikator UUID przestrzeni nazw (V1 lub V4) i przekazać go każdemu, kto tego potrzebuje. Jeśli masz kilka przestrzeni nazw, publikowanie identyfikatora UUID dla każdego z nich nie jest idealne.
Tutaj pojawia się hierarchia: tworzysz jeden „podstawowy” UUID (dowolnego typu), a następnie używasz go jako przestrzeni nazw do nazywania innych przestrzeni nazw! W ten sposób wystarczy opublikować podstawowy UUID (lub użyć oczywistego), a każdy może obliczyć resztę.
Na przykład, zostańmy, chcieliśmy stworzyć kilka UUID dla StackOverflow; który ma oczywistą nazwę w przestrzeni nazw DNS, więc podstawa jest oczywista:
Sam StackOverflow ma osobne przestrzenie nazw dla użytkowników, pytań, odpowiedzi, komentarzy itp., Ale są one również dość oczywiste:
To konkretne pytanie to # 10867405, więc jego UUID będzie wyglądał następująco:
Zauważ, że w tym procesie nie ma nic losowego, więc każdy, kto postępuje zgodnie z tą samą logiką, otrzyma tę samą odpowiedź, ale przestrzeń nazw UUID jest tak rozległa, że (efektywnie, biorąc pod uwagę bezpieczeństwo 122-bitowego skrótu kryptograficznego) nigdy nie zderzy się z UUID wygenerowany z dowolnej innej pary przestrzeń nazw / nazwa.
źródło