«Самая быстрая» хеш-функция реализована в Java, сравнивая часть файла - PullRequest
14 голосов
/ 12 апреля 2011

Мне нужно сравнить два разных файла экземпляра «Файл» в Java и хочу сделать это с помощью быстрой функции хеширования.

Идея: - Хэширование 20 первых строк в файле 1 - Хэширование 20первые строки в файле 2. Сравните два хеша и верните true, если они равны.

Я хочу использовать "самую быструю" хеш-функцию, когда-либо реализованную в Java.Какой бы вы выбрали?

Ответы [ 2 ]

28 голосов
/ 12 апреля 2011

Если вы хотите скорость, не хэшируйте! Особенно не криптографический хеш, как MD5. Эти хэши разработаны так, чтобы их нельзя было перевернуть, а не быстро вычислить. Вам следует использовать контрольную сумму - см. java.util.zip.Checksum и две ее конкретные реализации. Adler32 очень быстро вычисляет.

Любой метод, основанный на контрольных суммах или хэшах, уязвим для коллизий, но вы можете минимизировать риск, используя два разных метода, как RSYNC.

Алгоритм в основном:

  • Проверить размеры файлов равными
  • Разбить файлы на куски размером N байтов
  • Вычислить контрольную сумму для каждой пары совпадающих блоков и сравнить. Любые различия доказывают, что файлы не совпадают.

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

Чем больше битов в результате, тем меньше вероятность коллизии, но как только вы перебираете 64 бита, вы выходите за пределы того, что Java (и ЦП компьютера) может обрабатывать изначально, и, следовательно, становятся медленными, поэтому FNV-1024 менее вероятен чтобы дать вам ложный негатив, но гораздо медленнее.

Если все дело в скорости, просто используйте Adler32 и признайте, что очень редко разница не будет обнаружена. Это действительно редко. Подобные контрольные суммы используются, чтобы гарантировать, что Интернет может обнаружить ошибки передачи, и как часто вы получаете неправильные данные, появляющиеся?

На самом деле все дело в точности, вам придется сравнивать каждый байт. Больше ничего не будет работать.

Если вы можете пойти на компромисс между скоростью и точностью, существует множество вариантов.

2 голосов
/ 12 апреля 2011

Если вы сравниваете два файла одновременно в одной и той же системе, нет необходимости хэшировать их оба. Просто сравните байты в обоих файлах равны, как вы читаете оба. Если вы хотите сравнить их в разное время или в разных местах, MD5 будет быстрым и адекватным. Нет особой причины нуждаться в более быстром, если вы не имеете дело с действительно большими файлами. Даже мой ноутбук может хэшировать сотни мегабайт в секунду.

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

...