GetHashCode() дает разные результаты на разных серверах?
Я объявил строку кода C# примерно так
int hashcode = "apple".GetHashCode();
На моем компьютере, компьютере на работе и компьютере друга результат был 1657858284. На сервере разработки результат был 1548091822. Есть ли способ сказать мне, что проект всегда заставляет GetHashCode() выдавать 1657858284, независимо от того, на каком сервере он находится?
еще заметки Сначала я заметил, что есть различия в версиях... 1657858284 результаты пришли из.NET 3.5 и.NET 4.0. 1548091822 пришли из.NET 2.0.
Затем я сказал Visual Studio 2010 скомпилировать проект как проект.net 2.0, но он все равно дал мне 1657858284.
4 ответа
Возможно, вы используете 2 разные версии.Net. Это поведение отмечено в статье MSDN:
http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx
Из замечаний:
Реализация по умолчанию метода GetHashCode не гарантирует уникальные возвращаемые значения для разных объектов. Кроме того,.NET Framework не гарантирует реализацию по умолчанию метода GetHashCode, и возвращаемое значение будет одинаковым для разных версий.NET Framework. Следовательно, реализация по умолчанию этого метода не должна использоваться в качестве уникального идентификатора объекта для целей хеширования.
Как отметили другие, это соответствует документации. Вы не должны полагаться на то, что GetHashCode всегда возвращает одно и то же. Единственный инвариант, на который вы можете положиться, это то, что он будет возвращать одно и то же значение для того же объекта в том же домене приложения, если объект не был изменен каким-либо образом, который изменяет его семантику равенства. Если какое-либо из этих условий не выполняется - если два объекта находятся в разных доменах приложения или объект был видоизменен таким образом, что изменяет его семантику равенства - тогда у вас нет никаких гарантий, что "идентичные" объекты вернут один и тот же хеш код.
Единственное, для чего вы должны использовать хеш-код, это сбалансировать хеш-таблицу. Любое другое использование не по назначению и на ваш страх и риск. Не делай этого. Если вам нужен стабильный строковый хеш, который работает через произвольные границы, используйте алгоритм промышленного стандарта, такой как SHA256 или что-то в этом роде.
Смотрите мой архив статей о проблемах хеширования для получения более подробной информации, если эта тема вас интересует:
Чтобы ваши пользовательские классы возвращали стабильный хэш-код, вы должны переопределить метод GetHashCode(), иначе будет использован метод GetHashCode класса Object, который, я думаю, может сильно варьироваться. (Может даже быть конкретным экземпляром).
Если вам нужна контрольная сумма, которая, например, позволяет быстро проверить целостность данных при транспортировке, просто запустите ее через (криптографический) хеш с соответствующим количеством битов, как
- MD5
- SHA256
- SHA1
- fletcher
.Net-х GetHashCode
не предназначен для идентификации чего-либо (32 бита в любом случае приведут к коллизиям очень скоро, поэтому вы все равно не сможете использовать его для идентификации строки).
Обратите внимание, что даже вышеупомянутые четыре позволят столкновения (но менее скоро); поэтому обязательно используйте его только как контрольную сумму, а не как идентификацию.