2014-11-11 15 views
8

Próbuję napisać metodę generowania liczby całkowitej na podstawie dowolnego danego ciągu. Wywołując tę ​​metodę na dwóch identycznych ciągach, potrzebuję metody generowania tej samej dokładnej liczby całkowitej za każdym razem.Generowanie liczby całkowitej na podstawie dowolnego danego ciągu (bez kodu GetHashCode)

Próbowałem za pomocą .GetHasCode(), jednak jest to bardzo zawodna raz przenieść projekt do innej maszyny, jak GetHasCode() zwraca różne wartości dla tego samego łańcucha

Ważne jest również, że stopa kolizji BARDZO Niska. Metody niestandardowe, które napisałem do tej pory, powodują zderzenia już po kilkuset tysiącach rekordów.

Wartość mieszania MUSI być liczbą całkowitą. Wartość skrótu ciągów (np. Md5) sparowałaby mój projekt pod względem szybkości i obciążenia narzutowego.

Hashami całkowitymi są używane do wykonywania niezwykle szybkich wyszukiwań tekstowych, które mam pięknie działa, jednak obecnie opiera się na .GetHasCode() i nie działa, gdy zaangażowanych jest wiele maszyn.

Każdy wgląd byłby bardzo cenny.

+2

Czy realizowany algorytm znaną jako sugerowane [tutaj] (http://stackoverflow.com/a/6114944/1864167)? –

+1

Czy istnieją jakieś ograniczenia dotyczące struktury napisu (rozmiaru, kodowania)? – sternr

+0

Nie ma ograniczeń na wypowiedź, ale dowolny podany ciąg nie przekracza więcej niż stu znaków. – mrb398

Odpowiedz

4

MD5 mieszania powróci tablicy bajtów, które mogą być zamienione na całkowitą:

var mystring = "abcd"; 
MD5 md5Hasher = MD5.Create(); 
var hashed = md5Hasher.ComputeHash(Encoding.UTF8.GetBytes(mystring)); 
var ivalue = BitConverter.ToInt32(hashed, 0); 

oczywiście, są konwersji z 128 bitów mieszania do 32 bitów int więc niektóre informacje utraty, które będą zwiększyć możliwość kolizji. Możesz spróbować dostosować drugi parametr do ToInt32, aby sprawdzić, czy określone zakresy wartości skrótu MD5 powodują mniej kolizji niż inne dla danych.

+0

Dzięki za odpowiedź. To jest bardziej wydajna wersja tego samego kodu, który wymyśliłem kilka minut temu. Moja metoda daje teraz taki sam wynik na moim komputerze i serwerze. Mimo że MD5 działa w moim przypadku, czy MD5 kiedykolwiek będzie produkował inne wyniki na innym komputerze? – mrb398

+0

@ user1691808 md5 jest platformą agnostyczną. Dla tego samego wejścia, będzie wytwarzać tę samą wartość niezależnie od maszyny/języka. –

+0

Kolejna nuta czegoś, czego się nauczyłem, mysql BIGINT ma zawsze 8 bajtów i może przechowywać -9223372036854775808 do 9223372036854775807, co wydaje się być takim samym zakresem liczb całkowitych, jaki wytworzyłby kod wersji Int64 twojego kodu. Po prostu odrobina wiedzy, o której wcześniej nie wiedziałem. – mrb398

4

Jeśli twój kod skrótu tworzy duplikaty "po kilkuset tysiącach rekordów", masz całkiem niezłą implementację kodu skrótu.

Jeśli uzyskasz do the math, przekonasz się, że 32-bitowy kod skrótu ma 50% szans na utworzenie duplikatu po około 70 000 rekordów. Prawdopodobieństwo wygenerowania duplikatu po milionie rekordów jest tak bliskie pewności, że nie ma znaczenia.

Zgodnie z ogólną zasadą prawdopodobieństwo wygenerowania duplikatu kodu skrótu wynosi 50%, gdy liczba wpisów jest równa liczbie pierwiastków kwadratowych z liczby możliwych wartości. Zatem z 32-bitowym kodem mieszającym, który ma 2 32 możliwe wartości, szansa wygenerowania duplikatu wynosi 50% po około 2^16 (65 536) wartościach. Numer jest nieco większy - zbliża się do 70 000 - ale zasada pomaga dostać się do gry w piłkę.

Inną praktyczną zasadą jest to, że szansa wygenerowania duplikatu wynosi prawie 100%, gdy liczba elementów jest mieszana czterokrotnie w stosunku do pierwiastka kwadratowego. Dzięki 32-bitowemu kodowi skrótu prawie masz pewność, że zderzenie nastąpiło już po 2 hai 18 (262 144) hasłach.

To się nie zmieni, jeśli użyjesz MD5 i skonwertujesz go ze 128 bitów na 32 bity.

-1

Ten kod mapa dowolny ciąg do int między 0-100

int x= "ali".ToCharArray().Sum(x => x)%100; 
+0

Suma będzie miała rozkład normalny zamiast czegoś jednolitego, co zwiększy prawdopodobieństwo kolizji. – user1582024

Powiązane problemy