Wofür wird hashCode verwendet? Ist es einzigartig?

129

Ich getHashCode()stelle fest, dass es in WP7 in allen Steuerelementen und Elementen eine Methode gibt , die eine Folge von Zahlen zurückgibt. Kann ich diesen Hashcode verwenden, um einen Artikel zu identifizieren? Zum Beispiel möchte ich ein Bild oder einen Titel im Gerät identifizieren und den Aufenthaltsort überprüfen. Dies kann erfolgen, wenn der für bestimmte Elemente angegebene Hashcode eindeutig ist.

Können Sie mir erklären, wofür HashCode ist und wofür es getHashCode()verwendet wird?

Nghia Nguyen
quelle
Ich weiß, was hashCode bedeutet. Ich versuche, meinen Code viele Male auszuführen, um den Hashcode zu erhalten, und er gibt jedes Mal den gleichen Hashcode für die Sameitems zurück und scheint nicht dupliziert zu sein, aber ich bin mir nicht sicher. Nun, es ist in Ordnung, wenn Sie abstimmen wollen, es ist Ihre Meinung. Trotzdem danke für die Bearbeitung!
Nghia Nguyen
7
Ich empfehle, Eric Lipperts Richtlinien und Regeln für GetHashCode zu lesen , obwohl sie sich eher auf Regeln für die Implementierung von HashCodes als auf Regeln für deren Verwendung konzentrieren ... da sie " von Natur aus nur für eine Sache nützlich sind : das Einfügen eines Objekts in eine Hash-Tabelle"
Brian

Antworten:

108

MSDN sagt :

Ein Hash-Code ist ein numerischer Wert, mit dem ein Objekt während der Gleichheitsprüfung identifiziert wird. Es kann auch als Index für ein Objekt in einer Sammlung dienen.

Die GetHashCode-Methode eignet sich zur Verwendung in Hashing-Algorithmen und Datenstrukturen wie einer Hash-Tabelle.

Die Standardimplementierung der GetHashCode-Methode garantiert keine eindeutigen Rückgabewerte für verschiedene Objekte. Darüber hinaus garantiert .NET Framework nicht die Standardimplementierung der GetHashCode-Methode, und der zurückgegebene Wert ist zwischen verschiedenen Versionen von .NET Framework gleich. Folglich darf die Standardimplementierung dieser Methode nicht als eindeutige Objektkennung für Hashing-Zwecke verwendet werden.

Die GetHashCode-Methode kann von einem abgeleiteten Typ überschrieben werden. Werttypen müssen diese Methode überschreiben, um eine für diesen Typ geeignete Hash-Funktion bereitzustellen und eine nützliche Verteilung in einer Hash-Tabelle bereitzustellen. Zur Eindeutigkeit muss der Hash-Code auf dem Wert eines Instanzfelds oder einer Instanz anstelle eines statischen Felds oder einer statischen Eigenschaft basieren.

Objekte, die als Schlüssel in einem Hashtable-Objekt verwendet werden, müssen auch die GetHashCode-Methode überschreiben, da diese Objekte ihren eigenen Hash-Code generieren müssen. Wenn ein als Schlüssel verwendetes Objekt keine nützliche Implementierung von GetHashCode bietet, können Sie beim Erstellen des Hashtable-Objekts einen Hash-Code-Anbieter angeben. Vor der .NET Framework-Version 2.0 basierte der Hash-Code-Anbieter auf der System.Collections.IHashCodeProvider-Schnittstelle. Ab Version 2.0 basiert der Hash-Code-Anbieter auf der System.Collections.IEqualityComparer-Schnittstelle.

Grundsätzlich existieren Hash-Codes, um Hashtabellen zu ermöglichen.
Zwei gleiche Objekte haben garantiert gleiche Hashcodes.
Bei zwei ungleichen Objekten wird nicht garantiert, dass sie ungleiche Hashcodes haben (dies wird als Kollision bezeichnet).

SLaks
quelle
3
Das Zitat aus dem MSDN ist jetzt veraltet. Der MSDN ist jetzt nicht so explizit, dass der Hash-Code nicht eindeutig ist.
user34660
248

Nachdem ich gelernt hatte, worum es geht, dachte ich, eine hoffentlich einfachere Erklärung in Analogie zu schreiben:

Zusammenfassung: Was ist ein Hashcode?

  • Es ist ein Fingerabdruck. Mit diesem Fingerabdruck können wir interessierende Personen identifizieren.

Lesen Sie unten für weitere Details:

Stellen Sie sich einen Hashcode vor, während wir versuchen, jemanden eindeutig zu identifizieren

Ich bin ein Detektiv, der nach einem Verbrecher Ausschau hält. Nennen wir ihn Mr. Cruel. (Er war ein berüchtigter Mörder, als ich ein Kind war - er ist in ein Haus eingebrochen, hat ein armes Mädchen entführt und ermordet, ihren Körper abgeladen und ist immer noch auf freiem Fuß - aber das ist eine andere Sache). Herr Cruel hat bestimmte Besonderheiten, mit denen ich ihn in einem Meer von Menschen eindeutig identifizieren kann. Wir haben 25 Millionen Menschen in Australien. Einer von ihnen ist Herr Cruel. Wie können wir ihn finden?

Schlechte Möglichkeiten, Mr Cruel zu identifizieren

Anscheinend hat Herr Cruel blaue Augen. Das ist keine große Hilfe, da fast die Hälfte der Bevölkerung in Australien auch blaue Augen hat.

Gute Möglichkeiten, Herrn Cruel zu identifizieren

Was kann ich noch verwenden? Ich weiß: Ich werde einen Fingerabdruck verwenden!

Vorteile :

  • Es ist wirklich sehr schwer für zwei Personen, den gleichen Fingerabdruck zu haben (nicht unmöglich, aber äußerst unwahrscheinlich).
  • Der Fingerabdruck von Herrn Cruel wird sich nie ändern.
  • Jeder einzelne Teil des gesamten Wesens von Herrn Cruel: sein Aussehen, seine Haarfarbe, seine Persönlichkeit, seine Essgewohnheiten usw. müssen sich (idealerweise) in seinem Fingerabdruck widerspiegeln, so dass, wenn er einen Bruder hat (der sehr ähnlich, aber nicht gleich ist) - dann beides sollte haben verschiedene Fingerabdrücke. Ich sage "sollte", weil wir nicht 100% garantieren können, dass zwei Menschen auf dieser Welt unterschiedliche Fingerabdrücke haben.
  • Wir können jedoch immer garantieren, dass Herr Cruel immer den gleichen Fingerabdruck hat - und dass sich sein Fingerabdruck NIEMALS ändert.

Die obigen Eigenschaften sorgen im Allgemeinen für gute Hash-Funktionen.

Wie sieht es also mit "Kollisionen" aus?

Stellen Sie sich also vor, ich bekomme einen Hinweis und finde jemanden, der zu Mr. Cruels Fingerabdrücken passt. Bedeutet das, dass ich Herrn Cruel gefunden habe?

........vielleicht! Ich muss genauer hinsehen. Wenn ich SHA256 (eine Hashing-Funktion) verwende und in einer kleinen Stadt mit nur 5 Personen suche, dann besteht eine sehr gute Chance, dass ich ihn gefunden habe! Aber wenn ich MD5 (eine andere berühmte Hashing-Funktion) verwende und in einer Stadt mit + 2 ^ 1000 Personen nach Fingerabdrücken suche, ist es eine ziemlich gute Möglichkeit, dass zwei völlig unterschiedliche Personen denselben Fingerabdruck haben.

Was ist der Vorteil von all dem überhaupt?

Der einzige wirkliche Vorteil von Hashcodes besteht darin, dass Sie etwas in eine Hash-Tabelle einfügen möchten - und mit Hash-Tabellen möchten Sie Objekte schnell finden - und hier kommt der Hash-Code ins Spiel. Sie ermöglichen es Ihnen, Dinge wirklich in Hash-Tabellen zu finden schnell. Es ist ein Hack, der die Leistung massiv verbessert, aber mit einem geringen Aufwand an Genauigkeit.

Stellen wir uns also vor, wir haben einen Hash-Tisch voller Menschen - 25 Millionen Verdächtige in Australien. Mr Cruel ist irgendwo da drin ..... Wie können wir ihn wirklich schnell finden ? Wir müssen sie alle sortieren: um eine potenzielle Übereinstimmung zu finden oder um potenzielle Verdächtige auf andere Weise freizusprechen. Sie möchten nicht die einzigartigen Eigenschaften jeder Person berücksichtigen, da dies zu lange dauern würde. Was würden Sie stattdessen verwenden? Sie würden einen Hashcode verwenden! Ein Hashcode kann Ihnen sagen, ob zwei Personen unterschiedlich sind. Ob Joe Bloggs NICHT Mr Cruel ist. Wenn die Drucke nicht übereinstimmen, wissen Sie, dass es definitiv NICHT Mr Cruel ist. Aber wenn die Fingerabdrücke übereinstimmenAbhängig von der von Ihnen verwendeten Hash-Funktion stehen die Chancen gut, dass Sie Ihren Mann gefunden haben. Aber es ist nicht 100%. Der einzige Weg, auf dem Sie sicher sein können, besteht darin, weitere Nachforschungen anzustellen: (i) Hatte er / sie eine Gelegenheit / ein Motiv, (ii) Zeugen usw. usw.

Wenn Sie Computer verwenden und zwei Objekte denselben Hashcode-Wert haben, müssen Sie erneut untersuchen, ob sie wirklich gleich sind. Sie müssten beispielsweise prüfen, ob die Objekte z. B. dieselbe Größe, dasselbe Gewicht usw. haben, ob die Ganzzahlen gleich sind oder ob die customer_id übereinstimmt, und dann zu dem Schluss kommen, ob sie gleich sind. Dies erfolgt normalerweise möglicherweise durch Implementierung einer IComparer- oder IEquality-Schnittstelle.

Schlüsselübersicht

Ein Hashcode ist also im Grunde ein Fingerabdruck.

Digitaler Fingerabdruck - Bildattribut für Pixabay - Frei verfügbar unter: https://pixabay.com/de/finger-fingerprint-security-digital-2081169/

  1. Zwei verschiedene Personen / Objekte können theoretisch immer noch den gleichen Fingerabdruck haben. Oder mit anderen Worten. Wenn Sie zwei Fingerabdrücke haben, die gleich sind ......... dann müssen nicht beide von derselben Person / demselben Objekt stammen.
  2. Buuuuuut, dieselbe Person / dasselbe Objekt gibt immer denselben Fingerabdruck zurück .
  3. Das heißt, wenn zwei Objekte unterschiedliche Hash-Codes zurückgeben, wissen Sie mit 100% iger Sicherheit, dass diese Objekte unterschiedlich sind.

Es dauert gut 3 Minuten, bis Sie sich mit dem oben Gesagten vertraut gemacht haben. Vielleicht lesen Sie es ein paar Mal, bis es Sinn macht. Ich hoffe, das hilft jemandem, denn ich habe viel Kummer gebraucht, um alles zu lernen!

BKSpurgeon
quelle
1
Betreff: Die MSDN-Dokumentation hat einige meiner Gehirnzellen getötet ... und einige von mir an den Rand des Selbstmordes gebracht. nur gerettet, weil ich eingeschlafen
bin
Sie haben Ihre nette Erklärung mit diesem Sternchen-Kommentar am Ende vollständig zerstört.
Waldemar Gałęzinowski
Ich liebte es! hauptsächlich der Name "Mr.Cruel!
João Pedro Andrade Marques
Als echter Verbrechensfan ist dies wahrscheinlich meine beliebteste SO-Antwort ... je.
IfElseTryCatch
11

GetHashCode()wird verwendet, um die Verwendung des Objekts als Schlüssel für Hash-Tabellen zu unterstützen. (Ähnliches gibt es in Java usw.). Das Ziel ist, dass jedes Objekt einen eigenen Hash-Code zurückgibt. Dies kann jedoch häufig nicht absolut garantiert werden. Es ist jedoch erforderlich, dass zwei logisch gleiche Objekte denselben Hashcode zurückgeben.

Eine typische Implementierung einer Hash-Tabelle beginnt mit dem HashCode-Wert, nimmt einen Modul (wodurch der Wert innerhalb eines Bereichs eingeschränkt wird) und verwendet ihn als Index für ein Array von "Buckets".

Seand
quelle
8

Es ist nicht nur in WP7 verfügbar, sondern in allen .NET-Objekten. Es macht das, was Sie beschreiben, aber ich würde es nicht als eindeutige Kennung in Ihren Apps empfehlen, da nicht garantiert wird, dass es eindeutig ist.

Object.GetHashCode-Methode

Phil Sandler
quelle
4

Dies ist aus dem msdn-Artikel hier:

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

"Während Sie hören werden, dass Hash-Codes einen eindeutigen Wert für eine bestimmte Eingabe generieren, ist es technisch schwierig, zwei verschiedene Dateneingaben zu finden, die den gleichen Wert haben . Dies ist jedoch wahr Bestimmende Faktoren bezüglich der Wirksamkeit eines Hash-Algorithmus liegen in der Länge des generierten Hash-Codes und der Komplexität der zu hashenden Daten. "

Verwenden Sie einfach einen für Ihre Datengröße geeigneten Hash-Algorithmus, der eindeutige Hashcodes enthält.

Shree Harsha
quelle