Funkcja, która rozprowadza dane wejściowe

14

Chciałbym wiedzieć, czy istnieje funkcja od liczb n-bitowych do liczb n-bitowych, która ma następujące cechy:fa

  • fa powinien być bijectywny
  • Zarówno i powinny być obliczalne dość szybkofaf1
  • f powinien zwrócić liczbę, która nie ma znaczącej korelacji z wprowadzonymi danymi.

Uzasadnienie jest następujące:

Chcę napisać program działający na danych. Niektóre informacje o danych są przechowywane w drzewie wyszukiwania binarnego, w którym klucz wyszukiwania jest symbolem alfabetu. Z czasem dodałem kolejne symbole do alfabetu. Nowe symbole po prostu uzyskają następny bezpłatny numer. Dlatego drzewo zawsze będzie miało niewielkie odchylenie od mniejszych kluczy, co powoduje większe zrównoważenie, niż myślę, że powinno być potrzebne.

Moim pomysłem jest zmieszanie liczb symboli tak, aby były szeroko rozłożone w całym zakresie . Ponieważ liczby symboli mają znaczenie tylko na wejściu i wyjściu, co dzieje się tylko raz, zastosowanie takiej funkcji nie powinno być zbyt drogie.[ 0 , 2 64 - 1 ]f[0,2641]

Myślałem o jednej iteracji generatora liczb losowych Xorshift, ale tak naprawdę nie wiem, jak to cofnąć, chociaż teoretycznie powinno to być możliwe.

Czy ktoś zna taką funkcję?
Czy to dobry pomysł?

FUZxxl
źródło
1
Nie jestem ekspertem, ale chyba można użyć permutacji pseudolosowego (patrz na przykład szyfru Feistel )
Vor
Jeśli zasadniczo obliczasz funkcję skrótu, dlaczego nie użyć skrótu?
vonbrand
@vonbrand Hashing nie jest odwracalny. Patrz wymaganie nr 2
FUZxxl,
Dlaczego musi być odwracalny? Co jest złego w tym, że jest odwracalne przez wyszukiwanie?
vonbrand,
1
Możesz przechowywać (f (x), x) jako klucze.
adrianN

Odpowiedzi:

6

Możesz użyć skrótu Fibonacciego , a mianowicie

.hF(k)=k512k512

Dla dostać n liczb parami-wyraźny (o) równomiernie w [ 0 , 1 ] . Skalowanie do [ 1 .. M ] i zaokrąglanie (w dół) pozwala uzyskać równomierne rozłożenie liczb w tym przedziale.k=1,,nn[0,1][1..M]

Na przykład są to skalowane do [ 0..10000 ] (lewa pierwotna sekwencja, prawa posortowana):hfa(1),,hfa(200)[0..10000]

wprowadź opis zdjęcia tutaj

Jest to przykład tego, co Knuth nazywa multiplikatywnym haszowaniem . Dla rozmiarze słowo komputera, niektóre całkowitą stosunkowo prime do wag i M liczby adresów potrzebnych używamywZAwM.

h(k)=M.((kZAw)mod1)

jako funkcja mieszająca. Powyżej następuje (upewnij się, że możesz go obliczyć z wystarczającą precyzją). Chociaż działa to również z dowolną inną liczbą niewymierną pozaϕ-1, jest to jedna z dwóch liczb, które prowadzą do liczb „najbardziej równomiernie rozmieszczonych”.ZA/w=ϕ-1=5-12)ϕ-1

Znajdź więcej w The Art of Computer Programming , Tom 3 autorstwa Donalda Knutha (rozdział 6.4 ze strony 513 w drugim wydaniu). W szczególności dowiesz się, dlaczego uzyskane liczby są odrębne parami (przynajmniej jeśli ) i jak obliczyć funkcję odwrotną, jeśli użyjesz naturalnego A i w zamiast ϕ - 1 .nM.ZAwϕ-1

Raphael
źródło
1
Jak skutecznie obliczyć ? fa-1
frafl
1
@frafl Mam nadzieję, że moja edycja w jakiś sposób rozwiązuje problem. Oczywiste jest jednak, że te techniki mieszania nie są specjalnie zaprojektowane, aby były skutecznie odwracalne.
Raphael
Tak, zrobię to, głosuję za tym, jednak nie poleciłbym tego jako przyjętej odpowiedzi.
frafl
1

Dla wejść bit ta funkcja działa:k

hzash(n)=(nmod2)k2))2)k2)+nrejav2)k2)

Jest to odwracalne, ponieważ , i ma pary niesekwencyjne { n , m } , n < m , gdzie h a s h ( m ) < h a s h ( n ) . Uwaga: dane wyjściowe i wejściowe mogą się korelować, zwłaszcza jeśli dane wejściowe są w { 1 , , 2 khzash(hzash(n))=n{n,m},n<mhzash(m)<hzash(n).{1,,2)k2)-1}

Ref: Odwracalna funkcja skrótu

Reza
źródło
To wygląda prosto i ładnie. Zamierzam to przetestować.
FUZxxl,
1
1ρ
to całkiem jasne! dla 64-bitów (0x00000000FFFFFFFF) i powinieneś przesunąć (<<) 32 bity. Ta funkcja jest prosta, praktyczna i wystarczająco szybka w praktyce.
Reza
1
x{1,,2)32-1}2)32x