2016-04-25 7 views
1

Я хочу создать целочисленный хэш-код для строк, который останется постоянным навсегда; т.е. одна и та же строка должна всегда приводить к одному и тому же хэш-коду.Постоянный hashcode для строк

Хеш не должен быть криптографически защищен, он не будет использоваться для паролей или конфиденциальных данных.

Моя первая попытка состояла в использовании .net framework string.GetHashCode(). Однако при чтении источников я нашел следующий commment:

// We want to ensure we can change our hash function daily. 
// This is perfectly fine as long as you don't persist the 
// value from GetHashCode to disk or count on String A 
// hashing before string B. Those are bugs in your code. 
hash1 ^= ThisAssembly.DailyBuildNumber; 

Это показывает, что хэш-код не будет оставаться постоянным.

Если да, имеет ли каркас другой способ генерации повторяемых хэш-кодов? Или код из GetHashCode станет разумной отправной точкой для реализации моего собственного?

Я ищу что-то как можно более легкое и быстрое.
Я нашел System.Security.Cryptography.MD5, но это кажется излишним для простого хэш-кода int32, и я беспокоюсь о накладных расходах. По крайней мере, это потребует преобразования из строки в массив байтов и от байтового массива к int, а также для создания нового объекта MD5() для каждого хэша или управления некоторым статическим общим объектом MD5().

+1

Если вы используете Google для «алгоритма строкового хэш-кода», вы получите хорошие результаты. Нет необходимости кому-то копировать код и размещать его здесь. – usr

+0

Мне не нужен образец кода неизвестного качества для генерации хэш-кода, я ищу метод .net framework или комбинацию методов, поскольку это кажется фундаментальной необходимостью для любой структуры. Я был чрезвычайно удивлен тем, что string.GetHashCode, по-видимому, не полезен для этой цели, и я не смог найти подходящую альтернативу. Я бы также ожидал, что ответ поможет другим, а также мне, который показывает, где эта функциональность скрыта в рамках, или, альтернативно, что она не существует. – HugoRune

+0

Поисковый запрос, который, наконец, дал мне хороший результат, был «.net stable string hash code». – usr

ответ

9

Нет встроенного, перекрестная версия стабильная, способ получения хеш-кода строки.

Вы можете просто скопировать существующий код GetHashCode(), но исключить часть, которая добавляет номер сборки в качестве семени, и не использовать небезопасные вызовы, чтобы не допустить изменений в деталях реализации.

Вот полностью управляемая версия 64bit GetHashCode(), которая не использует рандомизацию и вернет то же значение для всех будущих версий .NET (если поведение int^char никогда не изменится).

public static class StringExtensionMethods 
{ 
    public static int GetStableHashCode(this string str) 
    { 
     unchecked 
     { 
      int hash1 = 5381; 
      int hash2 = hash1; 

      for(int i = 0; i < str.Length && str[i] != '\0'; i += 2) 
      { 
       hash1 = ((hash1 << 5) + hash1)^str[i]; 
       if (i == str.Length - 1 || str[i+1] == '\0') 
        break; 
       hash2 = ((hash2 << 5) + hash2)^str[i+1]; 
      } 

      return hash1 + (hash2*1566083941); 
     } 
    } 
} 
+0

btw это близко к текущему (4.5/4.6) фактическому GetHashCode в String.cs. –

+0

@JonathanNappee Я сказал, что это так, я даже связался с String.cs в ответе. Однако «реальный» использует указатели и полагается на деталь реализации того, как строки отображаются на «char *». Выполнение указателей будет немного быстрее, но это не так, как будущее доказательство, потому что изменение того, как строки хранятся в памяти, изменит хэш-код. –

+0

Мой плохой, не видел, куда указывала ссылка. –

Смежные вопросы