Если не гарантируется уникальность getHashCode () для строки или целого числа, зачем его использовать?

Как я написал в названии.

Если использовать getHashCode () в вашем приложении небезопасно, зачем его использовать? (для строк и целых чисел) Я хочу использовать его для пересечения методов и кроме методов в моделях Linq или создать свой собственный класс IEqualityCompare. Это похоже на шанс - если он не на 100% безопасен?

Или я что-то упустил?

Как указано в методе String.GetHashCode в https://docs.microsoft.com/

Важный

Если два строковых объекта равны, метод GetHashCode возвращает одинаковые значения. Однако не существует уникального значения хэш-кода для каждого уникального строкового значения. Разные строки могут возвращать один и тот же хэш-код.

Стабильность самого хэш-кода не гарантируется. Хеш-коды для идентичных строк могут различаться в разных реализациях .NET, в разных версиях .NET и на разных платформах .NET (например, 32-разрядных и 64-разрядных) для одной версии .NET. В некоторых случаях они могут даже различаться в зависимости от домена приложения. Это означает, что два последующих запуска одной и той же программы могут возвращать разные хэш-коды.

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

Наконец, не используйте хеш-код вместо значения, возвращаемого функцией криптографического хеширования, если вам нужен криптостойкий хеш-код. Для криптографических хэшей используйте класс, производный от класса System.Security.Cryptography.HashAlgorithm или System.Security.Cryptography.KeyedHashAlgorithm.

Дополнительные сведения о хэш-кодах см. В разделе Object.GetHashCode.


person Niklas    schedule 07.12.2019    source источник
comment
Хэши из GetHashCode не являются безопасными, но вам, вероятно, в любом случае не нужны безопасные хэши для Except и Intersect.   -  person Sweeper    schedule 07.12.2019
comment
Я предполагаю, что дело в двух последующих запусках, когда я никогда не наблюдал, чтобы два вызова string.GetHashCode в одном и том же домене приложения возвращали два разных HashCodes. Недавно я попытался использовать GetHashCode, чтобы оценить, совпадают ли мой сериализованный граф объектов и десериализованный граф на основе его значений GetHashCode, которые не совпадают с тем, что я перезапустил свое приложение. Только в моих юнит-тестах они были такими же, как и процесс вызова сериализации и десериализации.   -  person Venson    schedule 07.12.2019
comment
GetHashCode не предназначен для обеспечения безопасности. Единственная цель - создать индекс. В процитированной вами документации прямо говорится, что не использовать GetHashCode для безопасных хэшей, а использовать классы из пространства имен System.Security.Cryptography.   -  person Dennis_E    schedule 07.12.2019
comment
Вы никогда не используете only GetHashCode (), затем вы используете Equals () для проверки равенства. Дело в том, что хэш может значительно сократить количество тестов на равенство, которые вам нужно выполнить. Как это может привести к значительному ускорению кода, довольно хорошо показано в этом Q + А.   -  person Hans Passant    schedule 07.12.2019
comment
Если я правильно помню, основная реализация GetHashCode в .NET Framework должна была учитывать значение указателя, а для примитивных значений его положение в своей таблице строк (забыл, как вызывалась таблица)   -  person Venson    schedule 07.12.2019


Ответы (2)


Я думаю, что вас смущает то, что вы думаете, что этот хэш-код отображается на адрес значения, но это не совсем так.

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

Когда вы создаете IEqualityComparer, если вы можете заставить GetHashCode() возвращать уникальные значения, Dictionary или HashSet, использующие его, будут работать быстрее, чем при большом количестве дубликатов.

Отметьте этот пример:

public int GetShashCode(string ojb)
{
     return obj.Length;
}

хотя это делает его намного быстрее, чем цикл по всем строкам, но он не очень уникален (хотя он действителен)

Этот пример также действителен, но даже хуже:

public int GetShashCode(string ojb)
{
     return (int)obj[0];
}

Основываясь на содержании строки, которую вы можете догадаться, вы можете сделать гораздо лучшие хэш-коды (например, вы знаете, что это номер социального страхования в следующем формате: «XXX-XX-XXXX», где каждый X представляет собой цифру). быть отличным выбором:

public int GetShashCode(string ojb)
{
     return int.Parse(obj.Replace("-",""));
}
person Ashkan Mobayen Khiabani    schedule 07.12.2019

Если использовать getHashCode () в вашем приложении небезопасно, зачем его использовать?

GetHashCode имеет другой цель. Если вам нужен тест на равенство строк, вам, вероятно, следует использовать _ 2_ или ==, они гарантированно работают правильно.

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

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

Он просто отображает почти бесконечный набор строк на (сравнительно) очень ограниченный набор целых чисел. Вы можете использовать хэш-код, если вам нужно равномерно распределить большое количество строк по меньшим «корзинам». Хеш-коды широко используются в коллекциях на основе хешей, например HashSet < / а>.

В документации для GetHashCode упоминаются различные проблемы с этим методом:

  • Метод может генерировать разные результаты для одной и той же строки в разных доменах / машинах / версиях .Net. Это означает, что не рекомендуется хранить хэш извне как своего рода уникальный идентификатор для последующего использования;
  • Результат не является криптографически надежным, поэтому вам не следует использовать его, если вам нужна нерушимая соль пароля.

Конечно, это выглядит устрашающе, но все же GetHashCode достаточно хорош для коллекций в памяти, таких как HashSet или Dictionary.

Также см. Этот вопрос: Почему важно переопределить GetHashCode при переопределении метода Equals?

person default locale    schedule 07.12.2019