Подтвердить что ты не робот

Хэш-качество и стабильность String.GetHashCode() в .NET?

Мне интересно узнать о хеш-качества и хеш-стабильности, созданной реализацией String.GetHashCode() в .NET?

Что касается качества, я сосредоточен на алгоритмических аспектах (следовательно, качество хеша, поскольку оно влияет на большие хеш-таблицы, а не на проблемы безопасности).

Затем, что касается стабильности, я задаюсь вопросом о потенциальных проблемах с версиями, которые могут возникнуть с одной версии .NET до следующей.

Некоторые огни по этим двум аспектам будут очень оценены.

4b9b3361

Ответ 1

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

Однако, что касается стабильности, хеш-код, созданный на разных версиях фреймворка, не гарантирует, что он будет прежним, и он изменился в прошлом, поэтому вы абсолютно не должны полагаться на стабильный хеш-код между версиями (см. здесь ссылку, в которой он изменился между 1.1 и 2.0). Фактически, он даже отличается между 32-битными и 64-битными версиями одной и той же версии фреймворка; из документации:

Значение, возвращаемое GetHashCode, зависит от платформы. Для определенного строкового значения он отличается от 32-разрядной и 64-разрядной версий .NET Framework.

Ответ 2

Это старый вопрос, но я хотел бы внести свой вклад, указав эту ошибку Microsoft о качестве хэша.

Сводка: на 64b качество хеширования очень низкое, когда ваша строка содержит "\ 0" байты. В принципе, будет только хэширован только начало строки.

Если мне нравится, вы должны использовать .Net-строки для представления двоичных данных в качестве ключа для высокопроизводительных словарей, вам нужно знать об этой ошибке.

Слишком плохо, это WONTFIX... Как побочный элемент, я не понимаю, как они могли сказать, что изменение хэш-кода является нарушением изменений, когда код включает

// 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;

и хэш-код в любом случае уже отличается от x86/64b.

Ответ 3

Я только что наткнулся на связанную с этим проблему. На одном из моих компьютеров (64-разрядный) у меня возникла проблема, когда я обнаружил, что два разных объекта идентичны, за исключением (сохраненного) хэш-кода. Этот хэш-код был создан из строки... той же строки!

m_storedhash = astring.GetHashCode();

Я не знаю, как эти два объекта оказались с разными хэш-кодами, поскольку они были из одной строки, но я подозреваю, что произошло то, что в одном и том же .NET exe один из проектов библиотеки классов, на которые я полагаюсь, был установлен x86, а другой - ANYCPU, и один из этих объектов был создан в методе внутри класса lib x86, а другой объект (те же самые входные данные, то же самое) был создан в методе внутри библиотеки классов ANYCPU.

Итак, звучит ли это правдоподобно: внутри одного исполняемого файла в памяти (не между процессами) некоторый код мог работать с строкой x86 Framework. GetHashCode() и другой код x64 Framework string.GetHashCode()?

Ответ 4

Я знаю, что на самом деле это не означает значения качества и стабильности, которые вы указали, но стоит знать, что хеширование чрезвычайно больших строк может привести к исключению OutOfMemoryException.

https://connect.microsoft.com/VisualStudio/feedback/details/517457/stringcomparers-gethashcode-string-throws-outofmemoryexception-with-plenty-of-ram-available

Ответ 5

Качество хеш-кодов достаточно хорошее по назначению, т.е. они не вызывают слишком большого количества конфликтов при использовании строк в качестве словаря. Я подозреваю, что он будет использовать всю строку для вычисления хэш-кода, если длина строки достаточно короткая, для огромных строк она будет использовать только первую часть.

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