Split von coreutils (der Standard aufmeisten LinuxDistributionen) eine--filter
Optiondie Sie verwenden können:
7z e -so image.7z | split -b 1000000 --filter=md5sum
Ich möchte Prüfsummen von großen Dateien und Streams in Unix / Linux durchführen, und ich möchte viele Prüfsummen von jedem großen Teil der Datei / des Streams, alle 1 MB oder alle 10 MB.
Zum Beispiel habe ich ein Disk-Image, ein komprimiertes Disk-Image und die Kopie des Originaldatenträgers. Einige Bildteile können geändert werden. Die Festplatte ist 50 GB groß und es gibt ungefähr 50000 Blöcke mit 1 MB. Für jede Datei möchte ich 50 000 md5sum oder sha1sums erhalten, um einen Überblick über die Änderungen zu erhalten. Eine einzelne MD5-Summe wird mir nicht dabei helfen, den Änderungsoffset zu finden.
Diese Aufgabe ist für ein unkomprimiertes Festplattenabbild einfach. Das dd
Tool in for
Loop wird in bash mit Berechnungsoffsets verwendet und jeder 1 MB große Teil der Datei wird ausgewählt (übersprungen). Dasselbe mit der Platte:
for a in `seq 1 50000`; do echo -n "$a: "; dd if=image.src bs=1M count=1 skip=$a | md5sum; done
Aber jetzt möchte ich komprimiertes und unkomprimiertes Image vergleichen, ohne es auf die Festplatte zu entpacken. Ich habe einen 7z
Entpacker, der das Bild mit hoher Geschwindigkeit bis zu 150-200 MB / s (Optionen 7z e -so image.7z |
) auspacken kann . Aber was kann ich nach dem |
Symbol schreiben, um md5sum von allen Dateiteilen zu bekommen.
Split von coreutils (der Standard aufmeisten LinuxDistributionen) eine--filter
Optiondie Sie verwenden können:
7z e -so image.7z | split -b 1000000 --filter=md5sum
Etwas so einfaches wie dieses Perl-Skript würde wahrscheinlich ausreichen.
$amount = 1_000_000; while (read(STDIN, $buffer, $amount) > 0) { open MD5, "|md5"; print MD5 $buffer; close MD5; }
Fügen Sie dies ein foo.pl
und rufen Sie es wie perl foo.pl
am Ende Ihrer Pipeline auf.
Es scheint mir, dass Sie nach einem solchen Werkzeug suchen .
Aus der Readme-Datei von BigSync:
Bigsync ist ein Tool zum schrittweisen Backup einer einzelnen großen Datei an einem langsamen Ziel (Netzwerkmedien oder ein billiges NAS). Die häufigsten Fälle für bigsync sind Festplatten-Images, virtuelle Betriebssysteme, verschlüsselte Volumes und unformatierte Geräte.
Bigsync liest die Quelldatei in Stücken und berechnet dabei die Prüfsummen. Sie vergleicht sie mit zuvor gespeicherten Werten für die Zieldatei und überschreibt geänderte Blöcke, wenn die Prüfsummen abweichen.
Auf diese Weise minimieren wir den Zugriff auf langsame Zielmedien. Dies ist der Hauptpunkt der Existenz von bigsync.
Es war leicht, einen kleinen 1-MB-Hasher mit Hilfe von rhash
Tools ( librhash
Bibliothek) zu schreiben . Es gibt ein einfaches Perl-Skript, das Prüfsummen für jeden 1-MB-Teil des Standardeingabestroms erstellt. Es benötigt Crypt::Rhash
Bindungen von cpan
:
$ cpan (cpan) install Crypt::Rhash $ cat rhash1M.pl #!/usr/bin/perl # Compute md5 and sha1 sum of every 1 MB part of stream use strict; use local::lib; use Crypt::Rhash; my ($buf, $len, $i); my $r=Crypt::Rhash->new(RHASH_MD5|RHASH_SHA1); # we can add more hashes, like RHASH_TIGER etc binmode STDIN; $i=0; while($len= read STDIN,$buf,1024*1024){ print "$i+$len: \t"; # print offset $r->update($buf); print "md5:",$r->hash(RHASH_MD5), " sha1:", $r->hash(RHASH_SHA1),"\n"; $r->reset(); # reset hash calculator $i+=$len; }
Dieses Public-Domain-Skript gibt den +
Dezimalversatz aus, dann die Blockgröße, dann die Eingabesummen md5 und sha1.
Zum Beispiel haben 2 MB Nullen Summen:
$ dd if=/dev/zero of=zerofile bs=1M count=2 $ ./rhash1M.pl < zerofile 0+1048576: md5:b6d81b360a5672d80c27430f39153e2c sha1:3b71f43ff30f4b15b5cd85dd9e95ebc7e84eb5a3 1048576+1048576: md5:b6d81b360a5672d80c27430f39153e2c sha1:3b71f43ff30f4b15b5cd85dd9e95ebc7e84eb5a3
rsync
Das funktioniert folgendermaßen: Berechnen Sie eine Prüfsumme, um zu prüfen, ob sich Teile der Datei unterscheiden, bevor Sie etwas senden.
Ich bin nicht sicher, wie gut es mit so großen Dateien funktionieren würde, obwohl ich noch nie davon gehört habe, dass es Dateigrößenbeschränkungen gibt.
Pipe die Ausgabe an dieses Python 2-Skript, zum Beispiel 7z e -so image.7z | python md5sum.py
:
import sys, hashlib CHUNK_SIZE = 1000 * 1000 for chunk in iter(lambda: sys.stdin.read(CHUNK_SIZE), ''): print hashlib.new('md5', chunk).hexdigest()