web-dev-qa-db-de.com

Wie schreibe ich eine Hash-Funktion in C?

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.)

  • EIN Hash-tabelle ist nichts anderes als ein Array (ein- oder mehrdimensional) zum Speichern von Werten.
  • Hashing ist der Prozess, um den Index/Speicherort im Array zu finden, um die Daten einzufügen/abzurufen. Sie nehmen ein oder mehrere Datenelemente und übergeben es als Schlüssel an eine Hash-Funktion. Sie erhalten dann den Index bzw. die Position, an der die Daten eingefügt bzw. abgerufen werden sollen.

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?

  • Wie schreibe ich eine Hash-Funktion in C?
  • Gibt es Standards oder Richtlinien dafür?
  • Wie stellen wir sicher, dass die Ausgabe einer Hash-Funktion, d. H. Der Index, nicht außerhalb des Bereichs liegt?

Es wäre großartig, wenn Sie einige gute Links erwähnen könnten, um diese besser zu verstehen.

26
aks

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.

11
Jerry Coffin

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.

4
RossFabricant

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).

0
Anssi