Полный ли Hash у String.GetHashCode() ?
От: Nikolay_P_I  
Дата: 17.03.10 05:48
Оценка:
В разделе MSDN по Object.GetHashCode() Есть подраздел "Notes to Implementers" со следующей цитатой:

For example, the implementation of the GetHashCode method provided by the String class returns identical hash codes for identical string values. Therefore, two String objects return the same hash code if they represent the same string value. Also, the method uses all the characters in the string to generate reasonably randomly distributed output, even when the input is clustered in certain ranges (for example, many users might have strings that contain only the lower 128 ASCII characters, even though a string can contain any of the 65,535 Unicode characters).

Вопросы:

1) Точно ли, что ВСЕГДА возвращает одинаковые хеши для одинаковых строк ?
2) Насколько хэши "reasonably randomly distributed" ? То есть — есть ли смысл использовать встроенный хэш .NET по строке как ключ к базе данных по текстам размером 1кб-100Мб и 1Мб-1Гб или количество совпадений будет слишком велико ? Что тогда использовать ? SHA1ServiceProvider.ComputeCache() ?
3) Пункт 2 для данных до 100 символов. Понадобилось тут GUID делать по GetType().ToSting().
Re: Полный ли Hash у String.GetHashCode() ?
От: _FRED_ Черногория
Дата: 17.03.10 06:05
Оценка:
Здравствуйте, Nikolay_P_I, Вы писали:

N_P>В разделе MSDN по Object.GetHashCode() Есть подраздел "Notes to Implementers" со следующей цитатой:


N_P>For example, the implementation of the GetHashCode method provided by the String class returns identical hash codes for identical string values. Therefore, two String objects return the same hash code if they represent the same string value. Also, the method uses all the characters in the string to generate reasonably randomly distributed output, even when the input is clustered in certain ranges (for example, many users might have strings that contain only the lower 128 ASCII characters, even though a string can contain any of the 65,535 Unicode characters).


N_P>Вопросы:


N_P>1) Точно ли, что ВСЕГДА возвращает одинаковые хеши для одинаковых строк ?


Да.

N_P>2) Насколько хэши "reasonably randomly distributed" ? То есть — есть ли смысл использовать встроенный хэш .NET по строке как ключ к базе данных по текстам размером 1кб-100Мб и 1Мб-1Гб или количество совпадений будет слишком велико ? Что тогда использовать ? SHA1ServiceProvider.ComputeCache() ?


Что есть "ключ" в данном контексте? Ключи бывают уникальными и не уникальными. В качестве не-уникального мог бы подойти, но не подойдёт: от версии к версии фреймворка алгоритм String::GetHashCode может меняться.

N_P>3) Пункт 2 для данных до 100 символов. Понадобилось тут GUID делать по GetType().ToSting().


А без разницы — сто или мильён: из-за версиооности. Да и даже если забиться на какую-то строго-определённую версию, вряд ли алгоритм String::GetHashCode делался в расчёте на то, что его будут вызывать для стамегабайтных строк. Это как раз тот случай, когда количество требует решения качественно другого уровня.

P.S. Всё, что я написал, можно было бы узнать самому за несколько минут, набров в гугле String.GetHashCode и найдя, во-первых, ссылку на документацию:

Note: If two string objects are equal, the GetHashCode method returns identical values. However, there is not a unique hash code value for each unique string value. Different strings can return the same hash code.

и, во-вторых, на запись в блоге Эрика Липперта:

The .NET 2.0 CLR uses a different algorithm for string hashing than the .NET 1.1 CLR. If you are saving .NET 1.1 CLR hash values in a database then you will not be able to match them when you upgrade to 2.0. The hash algorithm was specifically NOT designed to be forward/backward compatible and we called that out in the documentation because we knew that it probably would not be.

Help will always be given at Hogwarts to those who ask for it.
Re[2]: Полный ли Hash у String.GetHashCode() ?
От: _FRED_ Черногория
Дата: 17.03.10 06:12
Оценка: 52 (5)
Здравствуйте, _FRED_, Вы писали:

N_P>>2) Насколько хэши "reasonably randomly distributed" ? То есть — есть ли смысл использовать встроенный хэш .NET по строке как ключ к базе данных по текстам размером 1кб-100Мб и 1Мб-1Гб или количество совпадений будет слишком велико ? Что тогда использовать ? SHA1ServiceProvider.ComputeCache() ?


_FR>…В качестве не-уникального мог бы подойти, но не подойдёт: от версии к версии фреймворка алгоритм String::GetHashCode может меняться.


Открыл исходник с реализацией String::GetHashCode(). "Коменты", как говорится, "доставляют":

#if DEBUG 
  // 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;
#endif


Help will always be given at Hogwarts to those who ask for it.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.