2013-05-08 20 views
6

jest deterministyczny javascript hashCode()?Czy deterministyczny jest parametr hashCode() języka Java?

Próbuję zaimplementować wyszukiwarkę dokumentów, która wykorzystuje algorytm minhashingu, a ja używam hashCode do wstępnych słów. Czy to samo słowo otrzyma ten sam skrót za każdym razem, gdy go uruchomię?

Czy otrzymam ten sam skrót, nawet jeśli uruchomię go z innego komputera (32-bitowego w stosunku do 64-bitowego)?

+1

Nie będę się na to zakładał ... Może się nawet zdarzyć, że hasz będzie powiązany z adresem obiektu, a potem może się zmienić nawet z jednego biegu na następny ... –

+0

Zobacz http: //stackoverflow.com/questions/1516843/java-object-hashcode-result-constant-across-all-jvms-systems – Annabelle

+0

Dlaczego nie poprosić znajomego o uruchomienie przykładowego fragmentu kodu i zobaczenie go? Dlaczego nie zamieścić wspomnianego krótkiego fragmentu kodu, aby wszyscy mogli to zrobić? :) Mówiąc to, * nie uważam *, że hashCode jest zgodny pomiędzy wieloma przebiegami, tylko że pozostaje w VM. – Shark

Odpowiedz

9

To zależy od klasy do którego się odnosimy. Baza Object.hashCode realizacja nie jest, ponieważ, jak stated in the documentation:

tyle, ile jest to racjonalnie praktyczne, metoda hashCode zdefiniowany przez obiekt klasy ma powrócić odrębne całkowitymi dla różnych obiektów. (Jest to zazwyczaj realizowane poprzez przekształcenie wewnętrzny adres obiektu do liczby całkowitej, ale technika ta realizacja nie jest wymagane przez język programowania JavaTM.)

adresy nie są deterministyczne, uważają, że czasami są nawet używany jako źródło entropii.

Ale, na przykład, String ma deterministycznego kod hash określa się następująco:

Formula from Wikpedia

(zdjęcie zaczerpnięte z Wikipedii)

W niektórych przypadkach nie jest nawet sensowne deterministyczny definicja kod skrótu.

+0

+1, ale powinieneś używać [javadoc] (http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#hashCode%28%29) jako odniesienia zamiast Wikipedii . – assylias

+2

Powiedziałem tylko, że obraz formuły został skopiowany z Wikipedii, a nie że użyłem go jako odnośnika. Wyjaśnione. –

4

umowy generalnej z hashcode jest jako Javadoc mówi:

Ilekroć jest wywoływane na tym samym obiekcie więcej niż jeden raz w trakcie wykonywania aplikacji Java, metoda hashCode musi konsekwentnie zwracają taką samą liczbę całkowitą, o ile nie informacje używane w porównywaniu równań na obiekcie są modyfikowane. Ta liczba całkowita nie musi pozostawać spójna od jednego wykonania aplikacji do innego wykonania tej samej aplikacji.

Is the same word going to get the same hash every time that I run it?

Podczas wykonywania aplikacji, powołując hashCode() na równych słów (zakładam, że słowo jest instancja String i equals() zostało zmienione w String) powinien zwrócić tę samą liczbę całkowitą.

EDIT Od javadoc dla String.hashCode() określa sposób kod hash ciąg jest obliczane jest deterministyczny.

Returns a hash code for this string. The hash code for a String object is 
computed as : 
s[0]*31^(n-1) + s 1 *31^(n-2) + ... + s[n-1]

+4

Twoja odpowiedź jest myląca. 'hashcode' jest dobrze zdefiniowany i deterministyczny dla Ciągów, niezależnie od tego, czy maszyna jest 32 czy 64 bitowa – assylias

+0

Edytowana !!!!!!!!!! – NINCOMPOOP

+1

@assylias Tak, co w rzeczywistości może być ryzykiem DoS! Osoba atakująca może skonstruować żądanie HTTP z wiązką łańcuchów znaków (zmiennych env i parametrów zapytania) celowo zaprojektowanych tak, aby miały tę samą wartość skrótu, zamieniając mapę skrótu ~ O (1) skutecznie na listę połączoną O (N). Womp womp. – yshavit

3

Mówiąc ogólnie o przedmiotach: tak nie jest.

Jednak jeśli mówimy specificially o String, a następnie obliczenie hashcode jest wyraźnie określony w API String.hashCode():

Zwraca kod skrótu dla tego ciągu.Kod skrótu dla obiektu ciąg znaków jest obliczana jako

s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] 

pomocą int arytmetyczne, gdzie y [i] jest postać ego łańcucha, n oznacza długość łańcucha, a^oznacza potęgowanie. (Wartość mieszania pustego ciągu wynosi zero.)

Innymi słowy: powinieneś być w stanie polegać na standardzie hash, który jest stabilny dla ciągów.