Другие люди опубликовали ответ - если вы используете четное число, то для вычисления хеша важны только последние символы в строке, так как влияние раннего символа будет смещено из регистра.
Теперь давайте рассмотрим, что происходит, когда вы используете множитель, такой как 31. Ну, 31 равен 32-1 или 2 ^ 5 - 1. Поэтому, когда вы используете это, ваше окончательное значение хеш-функции будет:
\ sum {c_i 2 ^ {5 (len-i)} - \ sum {c_i}
к сожалению, stackoverflow не понимает математическую нотацию TeX, поэтому вышеприведенное трудно понять, но его два суммирования по символам встрока, где первый сдвигает каждый символ на 5 битов для каждого последующего символа в строке.Таким образом, использование 32-разрядного компьютера приведет к смещению вершины для всех, кроме последних семи символов строки.
В результате использование множителя 31 означает, что хотя символы, отличные от последнегосемь влияют на строку, она полностью не зависит от их порядка.Если вы возьмете две строки, которые имеют одинаковые последние 7 символов, для которых другие символы также одинаковы, но в другом порядке, вы получите одинаковый хеш для обоих.Вы также получите тот же хеш для таких вещей, как «az» и «by», отличных от последних 7 символов.
Таким образом, использование простого множителя, хотя и намного лучше, чем четного, еще не оченьхорошо.Лучше использовать инструкцию поворота, которая сдвигает биты обратно в нижнюю часть, когда они сдвигаются из верхней части.Что-то вроде:
public unisgned hashCode(string chars)
{
unsigned h = 0;
for (int i = 0; i < chars.length; i++) {
h = (h<<5) + (h>>27); // ROL by 5, assuming 32 bits here
h += chars[i];
}
return h;
}
Конечно, это зависит от того, насколько ваш компилятор достаточно умен, чтобы распознать идиому для команды поворота и превратить ее в одну инструкцию для максимальной эффективности.
Это такжепо-прежнему существует проблема, заключающаяся в том, что замена 32-символьных блоков в строке даст одинаковое значение хеш-функции, поэтому оно далеко от сильного, но, вероятно, адекватно для большинства некриптографических целей