Числовой хеш-код фиксированной длины из строки переменной длины в c # - PullRequest
14 голосов
/ 14 февраля 2009

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

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

Ответы [ 3 ]

22 голосов
/ 14 февраля 2009

Я предполагаю, что вы делаете это, потому что вам нужно сохранить значение в другом месте и сравнить с ним. Таким образом, ответ Зака ​​(хотя и полностью правильный) может вызвать у вас проблемы, поскольку в контракте для 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)
}
6 голосов
/ 14 февраля 2009

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

int shorthash = "test".GetHashCode() % 100000000; // 8 zeros
if (shorthash < 0) shorthash *= -1;
0 голосов
/ 14 февраля 2009

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

...