Do czego służy hashCode? Czy jest wyjątkowy?

134

Zauważyłem, że getHashCode()w każdym kontrolce, elementach w WP7 jest metoda, która zwraca sekwencję liczb. Czy mogę użyć tego kodu skrótu do zidentyfikowania przedmiotu? Na przykład chcę zidentyfikować zdjęcie lub piosenkę w urządzeniu i sprawdzić, gdzie jest. Można to zrobić, jeśli hashcode podany dla określonych pozycji jest unikalny.

Czy możesz mi pomóc wyjaśnić, do czego służy kod hashCode getHashCode()?

Nghia Nguyen
źródło
Wiem, co oznacza hashCode, próbuję uruchomić swój kod wiele razy, aby uzyskać hashcode i zwraca ten sam hashcode dla tych samych elementów za każdym razem i nie wydaje się, aby był zduplikowany, ale po prostu nie jestem pewien. Cóż, w porządku, jeśli chcesz zagłosować przeciw, to Twoja opinia. Mimo wszystko dzięki za zmianę!
Nghia Nguyen
7
Polecam przeczytanie Wytycznych i reguł Erica Lipperta dla GetHashCode , chociaż koncentruje się na zasadach implementacji HashCode, a nie na zasadach ich używania ... ponieważ są one „ z założenia przydatne tylko do jednego: umieszczania obiektu w tablicy z haszowaniem”
Brian

Odpowiedzi:

110

MSDN mówi :

Kod skrótu to wartość liczbowa używana do identyfikacji obiektu podczas testowania równości. Może również służyć jako indeks obiektu w kolekcji.

Metoda GetHashCode jest odpowiednia do użycia w algorytmach wyznaczania wartości skrótu i ​​strukturach danych, takich jak tabela skrótów.

Domyślna implementacja metody GetHashCode nie gwarantuje unikatowych wartości zwracanych dla różnych obiektów. Ponadto .NET Framework nie gwarantuje domyślnej implementacji metody GetHashCode, a zwracana wartość będzie taka sama w różnych wersjach .NET Framework. W związku z tym domyślna implementacja tej metody nie może być używana jako unikatowy identyfikator obiektu do celów mieszania.

Metodę GetHashCode można zastąpić przez typ pochodny. Typy wartości muszą przesłonić tę metodę, aby zapewnić funkcję skrótu odpowiednią dla tego typu i zapewnić użyteczną dystrybucję w tabeli skrótów. Aby zapewnić unikalność, kod skrótu musi być oparty na wartości pola lub właściwości wystąpienia, a nie na statycznym polu lub właściwości.

Obiekty używane jako klucz w obiekcie Hashtable muszą również przesłonić metodę GetHashCode, ponieważ te obiekty muszą generować własny kod skrótu. Jeśli obiekt używany jako klucz nie zapewnia użytecznej implementacji GetHashCode, można określić dostawcę kodu skrótu podczas konstruowania obiektu Hashtable. Przed wersją .NET Framework w wersji 2.0 dostawca kodu skrótu był oparty na interfejsie System.Collections.IHashCodeProvider. Począwszy od wersji 2.0, dostawca kodu skrótu jest oparty na interfejsie System.Collections.IEqualityComparer.

Zasadniczo istnieją kody skrótów, które umożliwiają tworzenie tabel skrótów.
Gwarantujemy, że dwa równe obiekty mają równe kody skrótów. Nie ma gwarancji, że
dwa nierówne obiekty będą miały nierówne hashcodes (co jest nazywane kolizją).

SLaks
źródło
4
Cytat z MSDN jest obecnie nieaktualny. MSDN nie jest teraz tak jednoznaczne, że kod skrótu nie jest unikatowy.
user34660
255

Po zapoznaniu się z tym, o co w tym wszystkim chodzi, postanowiłem napisać, miejmy nadzieję, prostsze wyjaśnienie poprzez analogię:

Podsumowanie: Co to jest kod mieszający?

  • To odcisk palca. Możemy użyć tego odcisku palca do identyfikacji interesujących nas osób.

Przeczytaj poniżej, aby uzyskać więcej informacji:

Pomyśl o haszkodzie tak, jak o nas, próbując jednoznacznie zidentyfikować kogoś

Jestem detektywem szukającym przestępcy. Nazwijmy go Panem Okrutnym. (Był notorycznym mordercą, kiedy byłem dzieckiem - włamał się do domu porwanego i zamordował biedną dziewczynę, porzucił jej ciało i nadal jest na wolności - ale to osobna sprawa). Pan Cruel ma pewne szczególne cechy, których mogę użyć, aby jednoznacznie zidentyfikować go w morzu ludzi. W Australii mamy 25 milionów ludzi. Jednym z nich jest Pan Okrutny. Jak możemy go znaleźć?

Złe sposoby na zidentyfikowanie pana okrutnego

Najwyraźniej pan Cruel ma niebieskie oczy. To niewiele pomaga, ponieważ prawie połowa populacji Australii ma również niebieskie oczy.

Dobre sposoby na zidentyfikowanie pana okrutnego

Z czego jeszcze mogę skorzystać? Wiem: użyję odcisku palca!

Zalety :

  • Dla dwóch osób jest naprawdę trudno mieć ten sam odcisk palca (nie jest to niemożliwe, ale bardzo mało prawdopodobne).
  • Odcisk palca pana Cruela nigdy się nie zmieni.
  • Każda część całej istoty Pana Cruela: jego wygląd, kolor włosów, osobowość, nawyki żywieniowe itp. Muszą (najlepiej) znaleźć odzwierciedlenie w jego odcisku palca, tak że jeśli ma brata (który jest bardzo podobny, ale nie taki sam) - to jedno i drugie powinny mieć różne odciski palców. Mówię „należy”, ponieważ nie możemy zagwarantować w 100%, że dwie osoby na tym świecie będą miały różne odciski palców.
  • Ale zawsze możemy zagwarantować, że pan Cruel zawsze będzie miał ten sam odcisk palca - i że jego odcisk palca NIGDY się nie zmieni.

Powyższe cechy ogólnie składają się na dobre funkcje skrótu.

Więc o co chodzi z „zderzeniami”?

Więc wyobraź sobie, że dostanę trop i znajdę kogoś pasującego do odcisków palców pana Cruela. Czy to oznacza, że ​​znalazłem pana Okrutnego?

........być może! Muszę się bliżej przyjrzeć. Jeśli używam SHA256 (funkcja haszująca) i szukam małego miasteczka, w którym jest tylko 5 osób - to jest bardzo duża szansa, że ​​go znalazłem! Ale jeśli używam MD5 (kolejna słynna funkcja haszująca) i sprawdzam odciski palców w mieście z + 2 ^ 1000 osób, to jest całkiem dobra możliwość, że dwie zupełnie różne osoby mogą mieć ten sam odcisk palca.

Więc jakie są korzyści z tego wszystkiego?

Jedyną prawdziwą zaletą haszowania jest to, że chcesz umieścić coś w tablicy skrótów - a w przypadku tablic skrótów chciałbyś szybko znaleźć obiekty - i właśnie tam pojawia się kod skrótu. szybko. To hack, który znacznie poprawia wydajność, ale niewielkim kosztem dokładności.

Wyobraźmy sobie więc, że mamy stół do haszowania wypełniony ludźmi - 25 milionów podejrzanych w Australii. Pan Cruel jest gdzieś tam ..... Jak możemy go naprawdę szybko znaleźć ? Musimy przejrzeć je wszystkie: znaleźć potencjalne dopasowanie lub w inny sposób uniewinnić potencjalnych podejrzanych. Nie chcesz brać pod uwagę wyjątkowych cech każdej osoby, ponieważ zajęłoby to zbyt dużo czasu. Czego byś użył zamiast tego? Użyłbyś hashcode! Kod skrótu może powiedzieć, czy dwie osoby są różne. Czy Joe Bloggs NIE jest Panem Okrutnym. Jeśli odciski nie pasują, to wiesz, że to zdecydowanie NIE jest Mr Cruel. Ale jeśli odciski palców się zgadzająnastępnie, w zależności od użytej funkcji skrótu, istnieje duże prawdopodobieństwo, że znalazłeś swojego mężczyznę. Ale to nie jest 100%. Jedynym sposobem, aby mieć pewność, jest dalsze dochodzenie: (i) czy miał okazję / motyw, (ii) świadkowie itp.

Jeśli używasz komputerów, jeśli dwa obiekty mają tę samą wartość kodu skrótu, musisz ponownie zbadać, czy są naprawdę równe. np. musiałbyś sprawdzić, czy obiekty mają np. taką samą wysokość, taką samą wagę itp., czy liczby całkowite są takie same, czy też customer_id jest zgodne, a następnie dojść do wniosku, czy są takie same. jest to zazwyczaj wykonywane przez implementację interfejsów IComparer lub IEquality.

Kluczowe podsumowanie

Zasadniczo hashcode to odcisk palca.

Cyfrowy odcisk palca - atrybut obrazu dla Pixabay - swobodnie dostępny do użytku pod adresem: https://pixabay.com/en/finger-fingerprint-security-digital-2081169/

  1. Teoretycznie dwie różne osoby / przedmioty mogą nadal mieć ten sam odcisk palca. Innymi słowy. Jeśli masz dwa takie same odciski palców ......... nie muszą one pochodzić od tej samej osoby / przedmiotu.
  2. Buuuuuut, ta sama osoba / przedmiot zawsze zwróci ten sam odcisk palca .
  3. Oznacza to, że jeśli dwa obiekty zwracają różne kody skrótu, to wiesz ze 100% pewnością, że te obiekty są różne.

Obejście powyższego zajmie dobre 3 minuty. Może przeczytaj to kilka razy, aż będzie miało sens. Mam nadzieję, że to komuś pomogło, ponieważ nauczenie się tego wszystkiego wymagało wiele żalu!

BKSpurgeon
źródło
2
Odp .: Dokumentacja MSDN zabiła kilka z moich komórek mózgowych … doprowadziła kilka z nich na skraj samobójstwa. uratowany tylko dlatego, że zasnąłem;)
Shwrk
Zniszczyłeś całe swoje miłe wyjaśnienie tym komentarzem z gwiazdką na końcu.
Waldemar Gałęzinowski,
Kocham to! głównie nazwisko „Mr.Cruel!
João Pedro Andrade Marques
Jako prawdziwy fan kryminałów jest to prawdopodobnie moja najbardziej ulubiona odpowiedź TAK… kiedykolwiek.
IfElseTryCatch
11

GetHashCode()służy do obsługi używania obiektu jako klucza dla tabel skrótów. (Podobna rzecz istnieje w Javie itp.). Celem każdego obiektu jest zwrócenie odrębnego kodu skrótu, ale często nie można tego całkowicie zagwarantować. Wymagane jest jednak, aby dwa logicznie równe obiekty zwracały ten sam kod skrótu.

Typowa implementacja tablicy skrótów zaczyna się od wartości hashCode, przyjmuje moduł (w ten sposób ograniczając wartość w zakresie) i używa go jako indeksu do tablicy „segmentów”.

seand
źródło
8

Nie jest unikalny dla WP7 - jest obecny we wszystkich obiektach .Net. W pewnym sensie robi to, co opisujesz, ale nie polecam go jako unikalnego identyfikatora w twoich aplikacjach, ponieważ nie ma gwarancji, że będzie unikalny.

Metoda Object.GetHashCode

Phil Sandler
źródło
4

To pochodzi z artykułu msdn tutaj:

https://blogs.msdn.microsoft.com/tomarcher/2006/05/10/are-hash-codes-unique/

„Chociaż można usłyszeć, jak ludzie twierdzą, że kody skrótów generują unikalną wartość dla danego wejścia, faktem jest, że chociaż jest to trudne do wykonania, technicznie możliwe jest znalezienie dwóch różnych danych wejściowych, które mają tę samą wartość . Jednak prawda czynniki decydujące o skuteczności algorytmu wyznaczania wartości skrótu leżą w długości generowanego kodu skrótu i ​​złożoności danych, które są szyfrowane. "

Po prostu użyj algorytmu skrótu odpowiedniego do rozmiaru danych, a będzie on miał unikalne kody skrótu.

Shree Harsha
źródło