algorithm
Hash-Funktionen
Suche…
Einführung in Hashfunktionen
Die Hash-Funktion h()
ist eine willkürliche Funktion, die Daten x ∈ X
beliebiger Größe auf den Wert y ∈ Y
fester Größe y ∈ Y
: y = h(x)
. Für gute Hash-Funktionen gelten folgende Einschränkungen:
Hash-Funktionen verhalten sich wie eine gleichmäßige Verteilung
Hash-Funktionen sind deterministisch.
h(x)
sollte immer den gleichen Wert für ein gegebenesx
schnelle Berechnung (hat Laufzeit O (1))
Im Allgemeinen ist die Hash-Funktion kleiner als die Eingangsdatengröße: |y| < |x|
. Hash-Funktionen sind nicht umkehrbar oder mit anderen Worten, es kann eine Kollision sein: ∃ x1, x2 ∈ X, x1 ≠ x2: h(x1) = h(x2)
. X
kann eine endliche oder eine unendliche Menge sein und Y
ist eine endliche Menge.
Hash-Funktionen werden in vielen Bereichen der Informatik verwendet, beispielsweise in der Softwaretechnik, Kryptographie, Datenbanken, Netzwerken, maschinellem Lernen usw. Es gibt viele verschiedene Arten von Hash-Funktionen mit unterschiedlichen domänenspezifischen Eigenschaften.
Hash ist oft ein ganzzahliger Wert. In den Programmiersprachen gibt es spezielle Methoden zur Hashberechnung. In C#
GetHashCode()
Methode für alle Typen beispielsweise den Int32
Wert (32-Bit-Ganzzahl) zurück. In Java
jede Klasse die Methode hashCode()
bereit, die int
. Jeder Datentyp hat eigene oder benutzerdefinierte Implementierungen.
Hash-Methoden
Es gibt verschiedene Ansätze zur Bestimmung der Hash-Funktion. Ohne Verlust der Allgemeinheit sei x ∈ X = {z ∈ ℤ: z ≥ 0}
positive ganze Zahlen. Oft ist m
prim (nicht zu nahe an einer exakten Potenz von 2).
Methode | Hash-Funktion |
---|---|
Divisionsmethode | h(x) = x mod m |
Multiplikationsmethode | h(x) = ⌊m (xA mod 1)⌋, A ∈ {z ∈ ℝ: 0 < z < 1} |
Hash-tabelle
Hash-Funktionen, die in Hash-Tabellen zum Berechnen des Index in ein Array von Slots verwendet werden. Hash-Tabelle ist eine Datenstruktur zum Implementieren von Wörterbüchern (Schlüsselwertstruktur). Gute implementierte Hashtabellen haben O (1) Zeit für die nächsten Operationen: Einfügen, Suchen und Löschen von Daten nach Schlüssel. Es können mehrere Tasten auf denselben Steckplatz zugreifen. Es gibt zwei Möglichkeiten, die Kollision aufzulösen:
Verkettung: Die verkettete Liste wird zum Speichern von Elementen mit demselben Hashwert in Slot verwendet
Offene Adressierung: In jedem Steckplatz ist null oder ein Element gespeichert
Die nächsten Methoden werden verwendet, um die für die offene Adressierung erforderlichen Sondensequenzen zu berechnen
Methode | Formel |
---|---|
Lineares Antasten | h(x, i) = (h'(x) + i) mod m |
Quadratisches Sondieren | h(x, i) = (h'(x) + c1*i + c2*i^2) mod m |
Doppelhashing | h(x, i) = (h1(x) + i*h2(x)) mod m |
Dabei sind i ∈ {0, 1, ..., m-1}
, h'(x), h1(x), h2(x)
Hashfunktionen, c1, c2
sind positive Hilfskonstanten.
Beispiele
Es sei x ∈ U{1, 1000}, h = x mod m
. Die nächste Tabelle zeigt die Hash-Werte für den Fall, dass kein Prim und kein Prim steht. Fettgedruckter Text kennzeichnet dieselben Hashwerte.
x | m = 100 (keine Primzahl) | m = 101 (Primzahl) |
---|---|---|
723 | 23 | 16 |
103 | 3 | 2 |
738 | 38 | 31 |
292 | 92 | 90 |
61 | 61 | 61 |
87 | 87 | 87 |
995 | 95 | 86 |
549 | 49 | 44 |
991 | 91 | 82 |
757 | 57 | 50 |
920 | 20 | 11 |
626 | 26 | 20 |
557 | 57 | 52 |
831 | 31 | 23 |
619 | 19 | 13 |
Links
Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest und Clifford Stein. Einführung in Algorithmen.
Hashcodes für häufig verwendete Typen in C #
Die Hash-Codes, die von der GetHashCode()
-Methode für integrierte und allgemeine C # -Typen aus dem System
Namespace erstellt werden, sind unten aufgeführt.
Boolean
1 wenn Wert wahr ist, sonst 0.
Byte , UInt16 , Int32 , UInt32 , Single
Wert (ggf. in Int32 umgewandelt).
SByte
((int)m_value ^ (int)m_value << 8);
Verkohlen
(int)m_value ^ ((int)m_value << 16);
Int16
((int)((ushort)m_value) ^ (((int)m_value) << 16));
Int64 , doppelt
Xoder zwischen unteren und oberen 32 Bits der 64-Bit-Nummer
(unchecked((int)((long)m_value)) ^ (int)(m_value >> 32));
UInt64 , DateTime , TimeSpan
((int)m_value) ^ (int)(m_value >> 32);
Dezimal
((((int *)&dbl)[0]) & 0xFFFFFFF0) ^ ((int *)&dbl)[1];
Objekt
RuntimeHelpers.GetHashCode(this);
Die Standardimplementierung ist der Sync-Block-Index .
String
Die Hash-Code-Berechnung hängt vom Plattformtyp (Win32 oder Win64) ab, der Funktion der Verwendung von randomisiertem String-Hashing und dem Debug- / Release-Modus. Im Falle einer Win64-Plattform:
int hash1 = 5381;
int hash2 = hash1;
int c;
char *s = src;
while ((c = s[0]) != 0) {
hash1 = ((hash1 << 5) + hash1) ^ c;
c = s[1];
if (c == 0)
break;
hash2 = ((hash2 << 5) + hash2) ^ c;
s += 2;
}
return hash1 + (hash2 * 1566083941);
Werttyp
Das erste nicht statische Feld sucht und erhält seinen Hashcode. Wenn der Typ keine nicht statischen Felder hat, wird der Hashcode des Typs zurückgegeben. Der Hashcode eines statischen Mitglieds kann nicht verwendet werden, da das Berechnen in einer Endlosschleife endet, wenn es sich um denselben Typ wie der ursprüngliche Typ handelt.
Nullable <T>
return hasValue ? value.GetHashCode() : 0;
Array
int ret = 0;
for (int i = (Length >= 8 ? Length - 8 : 0); i < Length; i++)
{
ret = ((ret << 5) + ret) ^ comparer.GetHashCode(GetValue(i));
}