Jak uzyskać w 100% identyczne skompresowane pliki dla plików źródłowych, które różnią się tylko datą utworzenia?

8

Chcę móc kompresować plik bezstratnie, a jeśli oryginalny plik jest identyczny z plikiem innego użytkownika, chcę, aby oba nasze skompresowane pliki były zgodne, nawet jeśli daty oryginalnych plików są różne .

Chcę używać maksymalnie 1 GB pamięci RAM podczas kompresji. Skłaniam się ku algorytmowi asymetrycznemu, ponieważ pliki, które mam, są dość duże, a kompresja za pomocą LZMA1 „ultra” w 7-zipie zajmuje co najmniej godzinę na maszynie P4 z 1 GB pamięci RAM i nic więcej nie działa. Myślę, że do moich celów można użyć 7-zip i FreeARC. Próbowałem znaleźć polecenia, których powinienem używać, ale nie mam szczęścia.

edycja : należy wygenerować w 100% identyczne pliki, nawet jeśli daty utworzenia są inne. Powinno to być możliwe poprzez --nodates w Freearc oraz z ???? w 7 suwakach. Szukam równoważnego polecenia dla 7-zip i sposobu standaryzacji kompresji na wielu komputerach.

Andy
źródło
1
Czy jesteś pewien, że LZMA jest deterministyczna?
Ignacio Vazquez-Abrams,
2
Rozwiń część braku szczęścia .
fideli
2
Gdzie jest pytanie Każdy program kompresji powinien być bezstratny, chyba że jest specjalnie zaprojektowany jako stratny.
Wstrzymano do odwołania.

Odpowiedzi:

11

Utwórz kilka identycznych plików:

$ echo hello > file1.test
$ echo hello > file2.test

zgzipuj je ...

$ gzip file1.test
$ gzip file2.test

obserwuj pole znacznika czasu jako jedyną różnicę:

$ hexdump file1.test.gz

0000000 8b1f 0808 TIME STMP 0300 6966 656c 2e31
0000010 6574 7473 cb00 cd48 c9c9 02e7 2000 3a30
0000020 0636 0000 0000                         

Aby uzyskać więcej informacji na temat znacznika czasu, zobacz RFC

Teraz możesz albo wziąć MD5, który zaczyna się po bajcie 8, wyzerować te cztery bajty w swoich plikach i stracić ich znaczniki czasu, lub wyodrębnić CRC16 z tych gzips (zobacz także RFC, aby uzyskać informacje o tym, jak to wyodrębnić)

Lub możesz zapisać bez znacznika czasu:

$ echo test > file1.test
$ echo test > file2.test
$ gzip -n file1.test
$ gzip -n file2.test
$ md5sum file1.test.gz
cfe4ddf1c4c3891b4ff4a1269b42db82  file1.test.gz
$ md5sum file2.test.gz
cfe4ddf1c4c3891b4ff4a1269b42db82  file2.test.gz
Gareth Davidson
źródło
1
A jeśli żadne inne porty nie gzipsą dostępne dla systemu Windows, Cygwin je udostępnia.
Arjan
3

Nie jest to bezpośrednia odpowiedź na twoje pytanie, ale i tak może ci pomóc.

Dawno temu (inne tysiąclecie) miałem ten sam problem. Chcieliśmy wiedzieć, czy skompresowane pliki są takie same bez ich dekompresowania i porównywania.

Nasze rozwiązanie było uzyskać md5 pliku przed ściskając go, potem skompresowany plik i przemianowano go md5sum.zip (.zip lub .tar.gz lub .rar lub .whatever) . W ten sposób wiedzieliśmy, że jeśli dwa pliki mają tę samą nazwę (bez przyrostka), to są one identyczne.

Nifle
źródło
2
Fajnie, choć oczywiście wiedzieliśmy, że powinniśmy przeczytać , zakładaliśmy ;-)
Arjan
Jest to również miłe, ponieważ jest całkowicie niezależne od stopnia kompresji: pliki skompresowane utworzone przez różne programy lub przy użyciu różnych ustawień mogą nadal być rozpoznawane jako takie same.
Arjan
1
Ten artykuł próbuje rozwiązać ten sam problem ... medium.com/@mpreziuso/…
XCore
2

pristine-tar ma zhakowaną wersję gzip, która zawsze daje takie same wyniki (i inną dla bzip2). Wybierz wariant algorytmu i znacznik czasu i gotowe.

Tobu
źródło
1

Włam się do źródeł 7-zip. Tam, gdzie odczytuje datę pliku, po prostu wstaw kod, aby zmienić datę na 01.01.1997 lub cokolwiek innego - naprawionego dla wszystkich plików. Skompiluj pod inną nazwą i użyj jej.

kagali-san
źródło