Выезд Загрузка GWTC , который имеет реализацию точно, что Вы ищете.
Я бы лично избегал XOR - это означает, что любые два равных значения приведут к 0 - поэтому hash (1, 1) == hash (2, 2) == hash (3, 3 ) и т.д. Также hash (5, 0) == hash (0, 5) и т.д., который может иногда появляться. Я намеренно использовал его для хеширования набора - если вы хотите хешировать последовательность элементов, и вы не заботитесь об упорядочивании, это хорошо.
Я обычно использую:
unchecked
{
int hash = 17;
hash = hash * 31 + firstField.GetHashCode();
hash = hash * 31 + secondField.GetHashCode();
return hash;
}
Это та форма, которую предлагает Джош Блох в «Эффективной Java». В прошлый раз, когда я отвечал на аналогичный вопрос, мне удалось найти статью, в которой это обсуждалось подробно - IIRC, никто толком не знает, почему это работает хорошо, но это так. Его также легко запомнить, легко реализовать и легко расширить на любое количество полей.
Я бы порекомендовал использовать встроенные хеш-функции в System.Security.Cryptography, а не использовать собственные.
Если вы ищете скорость и не имеете слишком много коллизий, то XOR является самым быстрым. Чтобы предотвратить кластеризацию около нуля, вы можете сделать что-то вроде этого:
finalHash = hash1 ^ hash2;
return finalHash != 0 ? finalHash : hash1;
Конечно, некоторые прототипы должны дать вам представление о производительности и кластеризации.
Если ваши входные хэши одинакового размера, равномерно распределены и не связаны друг с другом, тогда XOR должно быть в порядке. Плюс это быстро.
Ситуация, для которой я предлагаю это, - это то, где вы хотите сделать
H = hash(A) ^ hash(B); // A and B are different types, so there's no way A == B.
, конечно, если можно ожидать, что A и B будут хешировать до одного и того же значения с разумной (не пренебрежимо малой) вероятностью, тогда вам не следует использовать XOR таким образом.