Почему GetHashCode не использует алгоритм хеш-кода инструмента SK.exe? - PullRequest
0 голосов
/ 26 февраля 2012

MSDN говорит :

"Реализация по умолчанию метода GetHashCode не гарантирует уникальные возвращаемые значения для различных объектов."

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

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

Ответы [ 4 ]

2 голосов
/ 26 февраля 2012

Недостаточно битов. GetHashCode () возвращает 32 из них, поэтому никогда не может быть более 4 миллиардов различных значений. Парадокс дня рождения значительно сокращает это. Строгое имя, генерируемое sn.exe (не sk.exe), использует хеш SHA1. Который возвращает 160 бит, учитывая 2 ^ 160 различных значений.

Это действительно большое число (1.4E48), обеспечивающее уникальность по количеству. Несколько похоже на Guid, который использует 128 бит. Не то же самое, генератор Guid гарантирует, что дублирование не может произойти, SHA1 не имеет такой гарантии.

GetHashCode имеет ограниченное количество битов, потому что основным требованием для метода является то, что он быстрый . За исключением предоставления индекса сегмента для хэшированных коллекций, его использование ускоряет тестирование на равенство. Чтобы сделать его полезным, GetHashCode должен быть на порядок быстрее, чем Equals (), Give или Take. Для этого необходимо обрезать множество углов, как правило, реализация GetHashCode для структуры, которая содержит ссылочные типы, например, возвращает только значение GetHashCode первого члена.

2 голосов
/ 26 февраля 2012

Это две совершенно разные вещи.

Функция GetHashCode() по определению возвращает (только) 32-разрядное целое число.Предполагается использовать быстрый алгоритм и не гарантирует (не может) гарантировать уникальность.ПК может быстро сгенерировать достаточно строк, чтобы показать коллизию.

Когда вы подпишете приложение (документ), вы получите намного больший хэш (например, 128 или 256 бит).Хотя в теории у вас все еще может быть столкновение, это не имеет практического значения.

1 голос
/ 16 июня 2013

Нет ограничений на количество объектов, которые программа может создать, вызвать GetHashCode() и отказаться от них. Однако существует ограничение в 4 294 967 296 различных значений GetHashCode(). Если программа вызывает GetHashCode 4 294 967 297 раз, по крайней мере один из этих вызовов должен вернуть значение, которое уже было возвращено ранее.

Теоретически было бы возможно, чтобы система сохранила пул значений хеш-кода, а для объектов, для которых отказались, их хэш-коды были возвращены в пул, чтобы GetHashCode() могла гарантировать, что она никогда не вернет то же значение, что и у любого другого живого объекта (при условии, что существует не более 4 294 967 296 живых объектов, как минимум). С другой стороны, хранение такой информации будет дорогостоящим и не принесет большой пользы. С практической точки зрения столь же хорошо, чтобы система генерировала произвольное число, либо когда объект создается, либо когда в первый раз вызывается GetHashCode(). Будут случайные коллизии, но, как правило, их недостаточно, чтобы беспокоить хорошо написанный код.

Кстати, я иногда думал, что для каждого объекта было бы полезно иметь 64-битный идентификатор, который гарантированно уникален, и который также будет ранжировать объекты в порядке их создания. 64-битный идентификатор никогда не будет переполнен в течение жизни любой предсказуемой программы, и возможность присвоить объектам ранжирование может быть полезной в некоторых сценариях кэширования или интернирования. Например, если программа генерирует некоторые большие объекты путем чтения данных из файлов и часто сканирует их, чтобы найти различия, она может часто находить объекты, которые содержат идентичные данные, но различаются. Если два разных объекта оказываются идентичными и взаимозаменяемыми, замена ссылки на более новый объект более старым может значительно ускорить будущие сравнения между ними; если многие совпадающие объекты сравниваются между собой, многие ссылки на более новые объекты заменяются ссылками на самые старые, без необходимости что-либо явно кэшировать. Однако при отсутствии каких-либо средств определения «возраста» такие подходы на самом деле не сработали бы, поскольку не было бы способа узнать, от какой ссылки следует отказаться в пользу другой.

0 голосов
/ 26 февраля 2012

Unrelated.Интересно, как можно связать эти два значения?

Тем не менее, добавим еще аргумент:

Хеш-код для значения «не может гарантировать» уникальность для разных значений.Но он «гарантирует» тот же хеш-код для данного значения / объекта!Это означает:

var hashOne = "SO".GetHashCode();
var hastTwo = "SO".GetHashCode();
Debug.Assert(hashOne==hashTwo); //The assertion would succeed.

SN просто генерирует случайное уникальное число без логики для экземпляра.

...