<p>J’utilise habituellement quelque chose de similaire à l’implémentation donnée dans le <em>fabuleux</em> <a href="https://rads.stackoverflow.com/amzn/click/com/0321356683">Effective Java</a> de Josh Bloch. C’est rapide et produit un hash assez bon qui a peu de chances de provoquer des collisions. Choisissez deux nombres premiers différents, par exemple 17 et 23, et faites :</p>
<pre><code class="lang-auto">public override int GetHashCode()
{
unchecked // Overflow is fine, just wrap
{
int hash = 17;
// Suitable nullity checks etc, of course 🙂
hash = hash * 23 + field1.GetHashCode();
hash = hash * 23 + field2.GetHashCode();
hash = hash * 23 + field3.GetHashCode();
return hash;
}
}
</code></pre>
<p>Comme noté dans les commentaires, vous pourriez trouver qu’il est préférable de multiplier par un grand nombre premier à la place. Apparemment 486187739 est un bon choix… et bien que la plupart des exemples que j’ai vus avec de petits nombres tendent à utiliser des nombres premiers, il existe au moins des algorithmes similaires où des nombres non premiers sont souvent utilisés. Dans l’exemple presque-<a href="https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function">FNV</a> plus loin, par exemple, j’ai utilisé des nombres qui apparemment fonctionnent bien – mais la valeur initiale n’est pas un nombre premier. (La constante de multiplication <em>est</em> un nombre premier cependant. Je ne sais pas exactement à quel point c’est important.)</p>
<p>C’est mieux que la pratique courante de faire un <code>XOR</code> des codes de hachage pour deux raisons principales. Supposons que nous ayons un type avec deux champs <code>int</code> :</p>
<pre><code class="lang-auto">XorHash(x, x) == XorHash(y, y) == 0 for all x, y
XorHash(x, y) == XorHash(y, x) for all x, y
</code></pre>
<p>D’ailleurs, l’algorithme précédent est celui actuellement utilisé par le compilateur C# pour les types anonymes.</p>
<p><a href="http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx">Cette page</a> donne pas mal d’options. Je pense que pour la plupart des cas, l’algorithme ci-dessus est « suffisamment bon » et qu’il est incroyablement facile à retenir et à implémenter correctement. L’alternative <a href="http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx#fnv">FNV</a> est tout aussi simple, mais utilise des constantes différentes et <code>XOR</code> au lieu de <code>ADD</code> comme opération de combinaison. Cela ressemble <em>quelque chose</em> comme</p>
<p><em>(Réponse tronquée)</em></p>