Переносится ли String.hashCode() на виртуальные машины, JDK и операционные системы?

StackOverflow https://stackoverflow.com/questions/190376

  •  06-07-2019
  •  | 
  •  

Вопрос

Недавно возник интересный вопрос.Мы наткнулись на некоторый код, который использует hashCode() в качестве источника соли для шифрования MD5, но в связи с этим возникает вопрос:будет hashCode() возвращать одно и то же значение для одного и того же объекта на разных виртуальных машинах, разных версиях JDK и операционных системах?Даже если это не гарантировано, изменилось ли это в какой-либо момент до настоящего времени?

Редактировать:Я действительно имею в виду String.hashCode() скорее, чем более общий Object.hashCode(), который, конечно, может быть переопределен.

Это было полезно?

Решение

Нет.От http://tecfa.unige.ch/guides/java/langspec-1.0/javalang.doc1.html:

Общий контракт хэш-код как образом:

  • Всякий раз, когда он вызывается для одного и того же объекта более одного раза во время выполнения приложения Java, Хэш-код должен последовательно возвращать одно и то же целое число.Целое число может быть положительным, отрицательным или нулевым.Это целое число, однако, необязательно оставаться согласованным от одного Java приложения к другому или от одного выполнения приложения к другому выполнение того же приложения.[...]

Другие советы

Это зависит от типа:

  • Если у вас есть тип, который не переопределил hashCode(), то он, вероятно, будет возвращать другой hashCode() каждый раз, когда вы запускаете программу.
  • Если у вас есть тип, который переопределяет hashCode(), но не документирует, как он вычисляется, для объекта с одинаковыми данными совершенно законно возвращать другой хэш при каждом запуске, при условии, что он возвращает один и тот же хэш при повторных вызовах в рамках одного и того же запуска.
  • Если у вас есть тип, который переопределяет hashCode() документированным образом, т.е.алгоритм является частью документированного поведения, тогда вы, вероятно, в безопасности.(java.lang.String документирует это, например.) Тем не менее, я бы все равно избегал полагающийся по этому поводу в общем принципе, лично.

Просто поучительная история из мира .NET:Я видел, как по крайней мере несколько человек испытывали боль, используя результат string.GetHashCode() в качестве хэша их пароля в базе данных.Алгоритм изменился между .NET 1.1 и 2.0, и внезапно все хэши стали "неправильными".(Джеффри Рихтер документирует почти идентичный случай в CLR через C #.) Когда хэш делает необходимо сохранить, я бы предпочел, чтобы оно было рассчитано таким образом, чтобы всегда гарантированно стабильная - напримерMD5 или пользовательский интерфейс, реализованный вашими типами с гарантией стабильности.

Согласно документам : хеш-код для объекта String вычисляется как

s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

Я не уверен, является ли это формальной спецификацией или просто реализацией Sun. По крайней мере, оно должно быть одинаковым на всех существующих виртуальных машинах Sun независимо от платформы или операционной системы.

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

Я хотел бы добавить, что вы можете переопределить hashCode () (не забывайте equals (), если вы это сделаете), чтобы ваши бизнес-объекты везде возвращали один и тот же hashCode. Эти объекты будут, по крайней мере, иметь предсказуемый hashCode.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top