Почему Zipping одного и того же контента дважды дает два файла с разными SHA1? - PullRequest
15 голосов
/ 15 марта 2012

Я столкнулся со странной проблемой с файлами git и zip.Мой скрипт сборки берет кучу HTML-страниц документации и упаковывает их в файл docs.zip. Затем я проверяю этот файл в git.

Проблема, с которой я сталкиваюсь, заключается в том, что каждый раз, когда я перезапускаю скрипт сборки и получаю новый zip-файл, новый zip-файл имеет другой SHA1, чем предыдущий запуск.Мой скрипт сборки вызывает задачу ant zip.Однако ручной вызов macOSX zip из оболочки Mac OS X дает мне другой sha1, если я дважды заархивирую один и тот же каталог.

Прогон 1:

zip foo.zip *
openssl sha1 foo.zip 
rm foo.zip 

Прогон 2:

zip foo.zip *
openssl sha1 foo.zip

Прогон 1 и прогон 2 дают разные SHA1, даже если содержимое не меняется между прогонами.В обоих случаях zip распечатывает точно те же файлы, что и zip, но это не означает, что в файл zip включены какие-либо файлы для конкретной ОС, такие как .DS_Store.

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

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

Ответы [ 3 ]

10 голосов
/ 15 марта 2012

Согласно Википедии http://en.wikipedia.org/wiki/Zip_(file_format) кажется, что у zip-файлов есть заголовки для времени последней модификации файла и даты последней модификации файла, поэтому любой zip-файл, зарегистрированный в git, будет выглядеть как git, если zip-файл перестроен из той жесодержание с.И кажется, что нет флага, который бы указывал не устанавливать эти заголовки.

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

9 голосов
/ 07 июля 2016

По умолчанию gzip сохраняет имя файла и отметку времени

%> gzip -help 2>&1 | grep -e '-n'
 -N --name            save or restore original file name and time stamp
 -n --no-name         don't save original file name or time stamp

%> gzip -V
Apple gzip 272

Использование опции -n:

%> tar cv foo/ | gzip -n > foo.tgz; shasum foo.tgz # sha256sum on Ubuntu

вы будете постоянно получать один и тот же хеш.

Попробуйте выше без -n, и вы должны видеть каждый раз новый хеш.

2 голосов
/ 25 мая 2018

Я успешно создал файлы с тем же SHA1, используя флаг -X (--no-extra) для zip.

Я создал папку и пару файлов для архивации, чтобы проверить ее, и, как и ожидалось, каждый раз получал разные хэши SHA1:

$ mkdir stuff
$ echo "Stuff 1" > stuff/stuff1.txt
$ echo "Stuff 2" > stuff/stuff2.txt
$ zip -r stuff.zip stuff/
  adding: stuff/ (stored 0%)
  adding: stuff/stuff1.txt (stored 0%)
  adding: stuff/stuff2.txt (stored 0%)

$ shasum stuff.zip
1c8be43ac859bb57603be1243da14022710d22bd  stuff.zip

$ shasum stuff.zip
1c8be43ac859bb57603be1243da14022710d22bd  stuff.zip

$ zip -r stuff.zip stuff/
updating: stuff/ (stored 0%)
updating: stuff/stuff1.txt (stored 0%)
updating: stuff/stuff2.txt (stored 0%)

$ shasum stuff.zip
73920362d0f7de74d87286502e03e7126fdc0a6a  stuff.zip

Однако, используя -X, я получаю тот же хеш после последовательного архивирования:

$ zip -r -X stuff.zip stuff/
updating: stuff/ (stored 0%)
updating: stuff/stuff1.txt (stored 0%)
updating: stuff/stuff2.txt (stored 0%)

$ shasum stuff.zip
1ed228b16d1ee803f26a8b1419f2eb3bf7fcb9f5  stuff.zip

$ zip -r -X stuff.zip stuff/
updating: stuff/ (stored 0%)
updating: stuff/stuff1.txt (stored 0%)
updating: stuff/stuff2.txt (stored 0%)

$ shasum stuff.zip
1ed228b16d1ee803f26a8b1419f2eb3bf7fcb9f5  stuff.zip

У меня нет времени копаться и выяснять, какая дополнительная информация вызывает всплывающую разницу в первом случае, но, возможно, это может помочь кому-то, пытающемуся ее решить. Также тестируется только на macOS 10.12.6.

...