Хэш-качество и стабильность String.GetHashCode() в .NET?
Мне интересно узнать о хеш-качества и хеш-стабильности, созданной реализацией String.GetHashCode()
в .NET?
Что касается качества, я сосредоточен на алгоритмических аспектах (следовательно, качество хеша, поскольку оно влияет на большие хеш-таблицы, а не на проблемы безопасности).
Затем, что касается стабильности, я задаюсь вопросом о потенциальных проблемах с версиями, которые могут возникнуть с одной версии .NET до следующей.
Некоторые огни по этим двум аспектам будут очень оценены.
Ответы
Ответ 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
Качество хеш-кодов достаточно хорошее по назначению, т.е. они не вызывают слишком большого количества конфликтов при использовании строк в качестве словаря. Я подозреваю, что он будет использовать всю строку для вычисления хэш-кода, если длина строки достаточно короткая, для огромных строк она будет использовать только первую часть.
Нет гарантии стабильности версий. В документации четко сказано, что алгоритм хеширования может меняться от одной версии к другой, так что хэш-коды предназначены для краткосрочного использования.