Как генерировать контрольную сумму для объекта Java

Я ищу решение генерировать контрольную сумму для любого типа объекта Java, который остается тем же для каждого выполнения приложения, которое производит тот же объект.

Я попробовал его Object.hashCode(), но в API говорится

.... Эта целочисленная потребность не остается последовательной от одного выполнения приложения к другому выполнению того же приложения.

14
задан Michal Kordas 9 November 2017 в 12:36
поделиться

7 ответов

У меня была аналогичная проблема (создание хорошего хэш-кода для файлов XML), и я обнаружил, что лучшим решением является использование MD5 через MessageDigest или, если вам нужно что-то более быстрое: Fast MD5 . Обратите внимание, что даже если Object.hashCode будет одинаковым каждый раз, он все равно будет слишком коротким (всего 32 бита) для обеспечения высокой уникальности. Я думаю, что 64 бита - это минимум для вычисления хорошего хеш-кода. Имейте в виду, что MD5 генерирует 128-битный хэш-код, что должно быть даже больше, чем необходимо в этой ситуации.

Конечно, чтобы использовать MessageDigest , вам необходимо сначала сериализовать (в вашем случае маршал) объект.

9
ответ дан 1 December 2019 в 06:23
поделиться

Если вы используете Eclipse IDE, тогда у нее есть действия (в меню «Источник») для генерации хэш-кода и функции равенства. Это позволяет вам выбирать атрибуты класса, который вы хотите в хэш-коде. Это похоже на использование уже предложенного подхода HashCodeBuilder.

В качестве альтернативы вы можете передать объект в байтовый массив и сгенерировать его MD5.

2
ответ дан 1 December 2019 в 06:23
поделиться

Хотите ли вы сделать это для всех объектов Java?

В этом случае hashCode () не работает.

Для некоторых классов hashCode () имеет более строгое определение, которое гарантирует равенство между исполнениями. Например, String имеет четко определенную реализацию hashCode . Аналогично List и Set имеют четко определенные значения при условии, что все объекты, которые они содержат , также имеют четко определенные значения (обратите внимание, что общий Collection. hashCode () не требует, чтобы значение было четко определено).

Для других классов вам придется рекурсивно использовать отражение с некоторой четко определенной формулой для построения контрольной суммы.

3
ответ дан 1 December 2019 в 06:23
поделиться

Если вы управляете источником, вы можете реализовать hashCode (), чтобы он был согласован от одного выполнения к другому.

4
ответ дан 1 December 2019 в 06:23
поделиться

Библиотека общих языков Apache предоставляет класс HashCodeBuilder , который помогает создавать хэш-код, который удовлетворяет вашим требованиям из свойств класса.

Пример:

   public int checksum() {
     // you pick a hard-coded, randomly chosen, non-zero, odd number
     // ideally different for each class
     return new HashCodeBuilder(17, 37).
       append(property1).
       append(property2).
       append(property3).
       toHashCode();
   }

См. Commons Lang API

2
ответ дан 1 December 2019 в 06:23
поделиться

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

Но если вы опишете проблему, которую пытаетесь решить, вы, вероятно, получите более точное решение.

5
ответ дан 1 December 2019 в 06:23
поделиться

Хеш-код в порядке. Либо данное переопределение класса равно , а также, в соответствии с требованиями контракта, хэш-код ). По контракту, если равно , возвращается истина хэш-код должен быть таким же.
Или класс не переопределяет равно . В этом случае разные исполнения вашего приложения не могут создать один и тот же объект, поэтому проблем нет.
Единственная проблема заключается в том, что некоторые классы (даже из Java API) разрывают контракт для , равного .

2
ответ дан 1 December 2019 в 06:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: