Во-первых, на практике это обычно не имеет большого значения. Большинство хеш-функций "достаточно хороши".
Но если вас это действительно волнует, вы должны знать, что это сам предмет исследования. Есть тысячи статей об этом. Вы все еще можете получить докторскую степень сегодня, изучая и разрабатывая алгоритмы хеширования.
Ваша вторая хеш-функция может быть немного лучше, потому что она, вероятно, должна отделить строку "ab"
от строки "ba"
. С другой стороны, это, вероятно, менее быстро, чем первая хеш-функция. Это может или не может иметь отношение к вашей заявке.
Я предполагаю, что хеш-функции, используемые для строк генома, сильно отличаются от тех, которые используются для хеширования фамилий в телефонных базах данных. Возможно, даже некоторые строковые хеш-функции лучше подходят для немецкого языка, чем для английского или французского слова.
Многие программные библиотеки предоставляют достаточно хорошие хэш-функции, например, Qt имеет qhash , а C ++ 11 имеет std :: hash в <functional>
, Glib имеет несколько хеш-функций в C и POCO имеет некоторую функцию hash .
У меня довольно часто есть функции хеширования, включающие простые числа (см. идентификатор Безу ) и xor, например,
#define A 54059 /* a prime */
#define B 76963 /* another prime */
#define C 86969 /* yet another prime */
#define FIRSTH 37 /* also prime */
unsigned hash_str(const char* s)
{
unsigned h = FIRSTH;
while (*s) {
h = (h * A) ^ (s[0] * B);
s++;
}
return h; // or return h % C;
}
Но я не претендую на звание эксперта по хешу. Конечно, значения A
, B
, C
, FIRSTH
предпочтительно должны быть простыми числами, но вы могли бы выбрать другие простые числа.
Посмотрите на реализацию MD5 , чтобы понять, какими могут быть хеш-функции.
В большинстве хороших книг по алгоритмике есть как минимум целая глава, посвященная хешированию. Начните с вики-страниц по хеш-функциям & хеш-таблица .