Числовой хэш-код фиксированной длины из строки переменной длины в С#

Мне нужно хранить номера фиксированной длины (до 8 цифр), созданные из строк переменной длины. Хэш не обязательно должен быть уникальным. Это просто нужно изменить при изменении строки ввода. Есть ли хеш-функция в .Net, которая делает это?

Спасибо
Кишор.

Ответы

Ответ 1

Я предполагаю, что вы делаете это, потому что вам нужно сохранить значение в другом месте и сравнить с ним. Таким образом, ответ Зака (хотя и полностью правильный) может вызвать у вас проблемы, поскольку в контракте для String.GetHashCode() явно указана область его изменения.

Таким образом, здесь есть фиксированная и легко повторяемая на других языках версия.

Я предполагаю, что вы будете знать во время компиляции количество доступных десятичных цифр. Это основано на хеше Jenkins One At Time Hash (реализованном и всесторонне протестированном Бретом Малви), так как оно обладает отличным поведением лавин (изменение одного бита на входе распространяется на все биты на выходе), что означает Ленивое уменьшение по модулю битов в конце не является серьезным недостатком для большинства применений (хотя вы могли бы добиться большего успеха при более сложном поведении)

const int MUST_BE_LESS_THAN = 100000000; // 8 decimal digits

public int GetStableHash(string s)
{
    uint hash = 0;
    // if you care this can be done much faster with unsafe 
    // using fixed char* reinterpreted as a byte*
    foreach (byte b in System.Text.Encoding.Unicode.GetBytes(s))
    {   
        hash += b;
        hash += (hash << 10);
        hash ^= (hash >> 6);    
    }
    // final avalanche
    hash += (hash << 3);
    hash ^= (hash >> 11);
    hash += (hash << 15);
    // helpfully we only want positive integer < MUST_BE_LESS_THAN
    // so simple truncate cast is ok if not perfect
    return (int)(hash % MUST_BE_LESS_THAN);
}

Ответ 2

Простой подход (обратите внимание, что это зависит от платформы):

int shorthash = "test".GetHashCode() % 100000000; // 8 zeros
if (shorthash < 0) shorthash *= -1;

Ответ 3

Используйте System.Security.Cryptography.MD5CryptoServiceProvider.ComputeHash, чтобы получить хеш MD5, усечь его до нужной длины.