GetHashCode() дает разные результаты на разных серверах?

Я объявил строку С# кода таким образом

int hashcode = "apple".GetHashCode();

На моем компьютере, компьютере на работе и другом компьютере, результат был 1657858284. На сервере разработки результат был 1548091822. Есть ли способ для меня, чтобы проект всегда делал GetHashCode() yield 1657858284, независимо от того, на каком сервере он включен?

больше примечаний Сначала я заметил, что разница в версиях... Результаты 1657858284 пришли из .NET 3.5 и .NET 4.0. 1548091822 пришел из .NET 2.0.

Затем я попросил визуальные студии 2010 скомпилировать проект как проект .net 2.0, но он все равно дал мне 1657858284.

Ответ 1

Возможно, вы используете 2 разных версии .Net. Такое поведение отмечено в статье MSDN:
http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx

Из замечаний:

Реализация метода GetHashCode по умолчанию не гарантирует уникальные возвращаемые значения для разных объектов. Кроме того,.NET Framework не гарантирует стандартную реализацию метода GetHashCode, и возвращаемое значение будет одинаковым для разных версий .NET Framework. Следовательно, реализация этого метода по умолчанию не должна использоваться как уникальный идентификатор объекта для целей хэширования.

Ответ 2

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

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

См. мой архив статей о проблемах хеширования для более подробной информации, если эта тема вас интересует:

http://blogs.msdn.com/b/ericlippert/archive/tags/hashing/

Ответ 3

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

Ответ 4

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

- MD5
- SHA256
- SHA1
- fletcher

.Net GetHashCode не означает ничего идентифицировать (32 бита в конечном итоге приведут к коллизиям, поэтому вы не сможете использовать его для идентификации строки в любом случае.)

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