Hash-Tabellen gelten als die schnellste/beste Methode zum Speichern/Abrufen von Daten.
Ich verstehe eine Hash-Tabelle wie folgt: (Bitte korrigieren Sie mich, wenn ich falsch liege, oder fügen Sie hinzu, wenn es noch etwas gibt.)
Ich habe eine Frage:
Wird die Hash-Funktion zum Speichern/Abrufen der Daten DIFFERENT von einer kryptografischen Hash-Funktion verwendet, die in Sicherheitsanwendungen zur Authentifizierung wie MD5, HMAC, SHA-1 usw. verwendet wird?
Inwiefern unterscheiden sie sich?
Es wäre großartig, wenn Sie einige gute Links erwähnen könnten, um diese besser zu verstehen.
Ein kryptographischer Hash betont, dass es für jeden schwierig ist, absichtlich eine Kollision zu erzeugen. Bei einer Hash-Tabelle liegt der Schwerpunkt normalerweise auf der Erzeugung einer angemessenen Streuung der Ergebnisse schnell . Daher sind die beiden in der Regel recht unterschiedlich (insbesondere ist ein kryptographischer Hash normalerweise ein lot langsamer).
Bei einer typischen Hash-Funktion ist das Ergebnis nur durch den Typ begrenzt, z. Wenn es ein size_t zurückgibt, ist es vollkommen in Ordnung, dass es any possible size_t zurückgibt. Es liegt an Ihnen, diesen Ausgabebereich auf die Größe Ihrer Tabelle zu reduzieren (z. B. durch den Rest der Division durch die Größe Ihrer Tabelle, die häufig eine Primzahl sein sollte).
Eine typische Hash-Funktion könnte beispielsweise so aussehen:
// warning: untested code.
size_t hash(char const *input) {
const int ret_size = 32;
size_t ret = 0x555555;
const int per_char = 7;
while (*input) {
ret ^= *input++;
ret = ((ret << per_char) | (ret >> (ret_size - per_char));
}
return ret;
}
Die Grundidee hierbei ist, dass jedes Bit der Eingabezeichenfolge das Ergebnis beeinflusst und (so schnell wie möglich) jedes Bit des Ergebnisses von mindestens einem Teil der Eingabe beeinflusst wird. Beachten Sie, dass ich dies nicht besonders als großartige Hash-Funktion empfehle - ich versuche nur, einige der Grundlagen zu erläutern, was Sie erreichen wollen.
Bob Jenkins schrieb eine ausführliche Beschreibung seiner guten, wenn auch etwas veralteten, Hash-Funktion . Der Artikel enthält Verknüpfungen zu neueren, besseren Hash-Funktionen, jedoch werden die Bedenken beim Erstellen einer guten Funktion berücksichtigt.
Die meisten Hashtabellenimplementierungen verwenden tatsächlich ein Array verknüpfter Listen, um Kollisionen aufzulösen. Wenn Sie nur ein Array verwenden möchten, muss die Hash-Funktion auf Kollisionen prüfen und einen neuen Hash-Index erstellen.
Die kryptografischen Hashfunktionen, die Sie erwähnen, können als Hashfunktionen für eine Hashtabelle Verwendet werden, sie sind jedoch viel langsamer als Hashfunktionen, die für eine Hashtabelle entwickelt wurden. Geschwindigkeit macht Brute-Force-Angriffe einfacher.
Die Designziele sind unterschiedlich.
Mit kryptografischen Hashfunktionen möchten Sie zum Beispiel, dass die Hash- und die Hash-Funktion nicht dazu verwendet werden können, die Originaldaten oder andere Daten zu ermitteln, die denselben Hash erzeugen würden.
Hash-Funktionen, die mit Hash-Tabellen und anderen Datenstrukturen verwendet werden, benötigen keine solchen Sicherheitseigenschaften. Es reicht oft aus, wenn die Hash-Funktion schnell ist und die Eingabe gleichmäßig in die Menge möglicher Hashes verteilt (um unnötiges Clustering/Kollisionen zu vermeiden).