Коммутативная аккумуляторная функция для расчета дайджеста нескольких хешей - PullRequest
5 голосов
/ 07 июля 2010

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

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

Единственные два метода, о которых я могу думать:

  1. Рассчитать MD5 конкатенации всех хэшей содержимого файла.Чтобы получить нужные свойства хеша, мне нужно было бы перечислить все файлы в каталоге, отсортировать их по хешу, объединить отсортированные хеши, а затем запустить MD5 для объединения.Это кажется медленнее, чем хотелось бы.Я могу сделать сортировку довольно эффективно, используя сортировку слиянием при расчете хэшей содержимого каталога по всему дереву, но я не могу обойтись при вычислении большого количества хешей MD5 на больших входах.

  2. Объединениесодержимое файла хэши с использованием XOR.Каждому каталогу нужно только XOR хэши содержимого файла и хэши содержимого каталога своих непосредственных потомков.Это очень быстро и просто, но не очень устойчиво к столкновениям.Он даже не может определить разницу между каталогом, который содержит 1 экземпляр файла, и каталогом, который содержит три экземпляра одного и того же файла.

Было бы неплохо, если бы была функция, которая может использоваться аналогично тому, как XOR используется в методе # 2, но является более устойчивой к столкновениям.Я думаю, что метод № 1 был бы достаточно быстрым для этого конкретного случая, но в интересах изучения всех вариантов / интеллектуального любопытства / будущих приложений, я хотел бы знать, есть ли функция, которая удовлетворяет описанию вназвание (у меня смутное воспоминание о том, что я уже несколько раз хотел такую ​​функцию).

Спасибо.

Ответы [ 3 ]

5 голосов
/ 07 июля 2010

Заказать независимое хеширование коллекций хэшей (по сути, то, что вы ищете, не так ли?)

Похоже, что любая независимая от ордера операция (например, сложение или умножение) подойдет вам.Добавление имеет преимущество переполнения в хорошем смысле.Я не помню, будет ли работать умножение.

Короче: добавьте все свои значения, игнорируя переполнение, и вы должны получить что-то полезное.Любая другая подобная функция должна справиться, если сложение недостаточно устойчиво к столкновениям.

4 голосов
/ 11 июля 2010

Поскольку количество предметов важно, но порядок не важен; просто отсортируйте список хэшей, а затем хэш-список.

find . -print0 | xargs -0 sha1sum | cut -c -40 | sort | sha1sum

Это даст тип значения хеша, которое является инвариантным к расположению каталога.

0 голосов
/ 22 апреля 2014

Если у вас есть доступ к Google guava, он предоставляет служебный метод Hashing.combinedUnordered (), который делает то, что вы хотите. (Внутренне это реализуется путем добавления всех хешей вместе.)

https://code.google.com/p/guava-libraries/wiki/HashingExplained

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...