Qu'est-ce qu'une bonne fonction de hachage? J'ai vu beaucoup de fonctions et d'applications de hachage dans mes cours sur les structures de données à l'université, mais j'ai surtout compris qu'il est assez difficile de créer une bonne fonction de hachage. En règle générale, pour éviter les collisions, mon professeur a dit que:
function Hash(key)
return key mod PrimeNumber
end
(mod est l'opérateur% en C et langages similaires)
le nombre premier étant la taille de la table de hachage. Je comprends que c'est une fonction plutôt bonne pour éviter les collisions et une fonction rapide, mais comment puis-je en faire une meilleure? Existe-t-il de meilleures fonctions de hachage pour les touches de chaîne par rapport aux touches numériques?
algorithm
language-agnostic
hash
Hoffmann
la source
la source
Réponses:
Pour faire des recherches de table de hachage "normales" sur pratiquement n'importe quel type de données - celle de Paul Hsieh est la meilleure que j'ai jamais utilisée.
http://www.azillionmonkeys.com/qed/hash.html
Si vous vous souciez de la sécurité cryptographique ou de toute autre chose plus avancée, alors YMMV. Si vous voulez juste une fonction de hachage à usage général kick ass pour une recherche de table de hachage, c'est ce que vous recherchez.
la source
Il n'y a pas de «bonne fonction de hachage» pour les hachages universels (éd. Oui, je sais qu'il existe un «hachage universel» mais ce n'est pas ce que je voulais dire). En fonction du contexte, différents critères déterminent la qualité d'un hachage. Deux personnes ont déjà mentionné SHA. Il s'agit d'un hachage cryptographique et il n'est pas du tout bon pour les tables de hachage, ce que vous voulez probablement dire.
Les tables de hachage ont des exigences très différentes. Cependant, trouver une bonne fonction de hachage de manière universelle est difficile car différents types de données exposent différentes informations qui peuvent être hachées. En règle générale, il est bon de considérer toutes les informations qu'un type détient de la même manière. Ce n'est pas toujours facile ni même possible. Pour des raisons de statistiques (et donc de collision), il est également important de générer une bonne répartition sur l'espace du problème, c'est-à-dire tous les objets possibles. Cela signifie que lors du hachage de nombres entre 100 et 1050, il n'est pas bon de laisser le chiffre le plus significatif jouer un grand rôle dans le hachage car pour ~ 90% des objets, ce chiffre sera 0. Il est bien plus important de laisser les trois derniers les chiffres déterminent le hachage.
De même, lors du hachage de chaînes, il est important de prendre en compte tous les caractères - sauf s'il est connu à l'avance que les trois premiers caractères de toutes les chaînes seront les mêmes; considérer ces derniers est alors un gaspillage.
C'est en fait l'un des cas où je conseille de lire ce que Knuth a à dire dans The Art of Computer Programming , vol. 3. Une autre bonne lecture est The Art of Hashing de Julienne Walker .
la source
Les fonctions de hachage ont deux objectifs principaux:
Il est impossible de recommander un hachage sans savoir à quoi vous l'utilisez.
Si vous créez simplement une table de hachage dans un programme, vous n'avez pas à vous soucier de la réversibilité ou du piratage de l'algorithme ... SHA-1 ou AES est complètement inutile pour cela, vous feriez mieux d'utiliser une variante de FNV . FNV réalise une meilleure dispersion (et donc moins de collisions) qu'un simple mod principal comme vous l'avez mentionné, et il est plus adaptable à différentes tailles d'entrée.
Si vous utilisez les hachages pour masquer et authentifier des informations publiques (telles que le hachage d'un mot de passe ou d'un document), vous devez utiliser l'un des principaux algorithmes de hachage examinés par le public. Le salon Hash Function est un bon point de départ.
la source
Ceci est un exemple de bon et aussi un exemple de pourquoi vous ne voudriez jamais en écrire un. C'est un hachage Fowler / Noll / Vo (FNV) qui est à la fois génie de l'informatique et pur vaudou:
Éditer:
la source
Je dirais que la règle générale est de ne pas rouler le vôtre. Essayez d'utiliser quelque chose qui a été soigneusement testé, par exemple, SHA-1 ou quelque chose du genre.
la source
Une bonne fonction de hachage a les propriétés suivantes:
Étant donné le hachage d'un message, il est impossible à un attaquant de trouver un autre message de telle sorte que ses hachages soient identiques.
Étant donné une paire de messages, m 'et m, il est impossible de trouver deux messages tels que h (m) = h (m')
Les deux cas ne sont pas les mêmes. Dans le premier cas, il existe un hachage préexistant pour lequel vous essayez de trouver une collision. Dans le second cas, vous essayez de trouver les deux messages qui entrent en collision. La deuxième tâche est beaucoup plus facile en raison du «paradoxe» de l'anniversaire.
Lorsque les performances ne sont pas un problème majeur, vous devez toujours utiliser une fonction de hachage sécurisée. Il existe des attaques très intelligentes qui peuvent être effectuées en forçant des collisions dans un hachage. Si vous utilisez quelque chose de fort dès le départ, vous vous protégerez contre ceux-ci.
N'utilisez pas MD5 ou SHA-1 dans de nouvelles conceptions. La plupart des cryptographes, moi inclus, les considéreraient comme cassés. La principale source de faiblesse dans ces deux conceptions est que la seconde propriété, que j'ai soulignée ci-dessus, ne vaut pas pour ces constructions. Si un attaquant peut générer deux messages, m et m ', que les deux hachent à la même valeur, ils peuvent utiliser ces messages contre vous. SHA-1 et MD5 souffrent également d'attaques par extension de message, ce qui peut fatalement affaiblir votre application si vous ne faites pas attention.
Un hachage plus moderne tel que Whirpool est un meilleur choix. Il ne souffre pas de ces attaques par extension de message et utilise les mêmes mathématiques que celles utilisées par AES pour prouver la sécurité contre diverses attaques.
J'espère que cela pourra aider!
la source
Ce que vous dites ici, c'est que vous voulez en avoir un qui utilise une résistance aux collisions. Essayez d'utiliser SHA-2. Ou essayez d'utiliser un (bon) chiffrement par bloc dans une fonction de compression à sens unique (jamais essayé auparavant), comme AES en mode Miyaguchi-Preenel. Le problème avec cela est que vous devez:
1) avoir une IV. Essayez d'utiliser les 256 premiers bits des parties fractionnaires de la constante de Khinchin ou quelque chose comme ça. 2) ont un schéma de remplissage. Facile. Barrow à partir d'un hash comme MD5 ou SHA-3 (Keccak [prononcé 'ket-chak']). Si vous ne vous souciez pas de la sécurité (quelques autres l'ont dit), regardez FNV ou lookup2 de Bob Jenkins (en fait, je suis le premier à recommander lookup2) Essayez également MurmurHash, c'est rapide (vérifiez ceci: .16 cpb ).
la source