Berechnen Sie die md5sum von jedem 1-MB-Teil des Streams aus der Pipe

1774
osgx

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 ddTool in forLoop 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 7zEntpacker, 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.

2

6 Antworten auf die Frage

6
Cristian Ciupitu

Split von coreutils (der Standard aufmeisten LinuxDistributionen) eine--filterOptiondie Sie verwenden können:

7z e -so image.7z | split -b 1000000 --filter=md5sum 
Flott. Ich wusste nichts davon. Kyle Jones vor 9 Jahren 0
2
Kyle Jones

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.plund rufen Sie es wie perl foo.plam Ende Ihrer Pipeline auf.

Coole Version, danke. Ich habe gerade meine eigene Version von `Crypt :: Rhash` fertiggestellt (md5 + sha1 + Tiger - immer noch ziemlich schnell). Sie können meinen Code ändern, um die Lesbarkeit und den Stil zu verbessern. osgx vor 9 Jahren 0
Und das Skript zeigt, dass meine Bilder meiner Festplatte ähneln, aber nicht gleich sind. Ich habe fast 50 GB eindeutige Daten zerstört. osgx vor 9 Jahren 0
0
Luis

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.

"Bigsync liest die Quelldatei in Stücken und berechnet Prüfsummen für jeden" - dieser Teil ist richtig, aber ich möchte nichts ändern. osgx vor 9 Jahren 0
0
osgx

Es war leicht, einen kleinen 1-MB-Hasher mit Hilfe von rhashTools ( librhashBibliothek) zu schreiben . Es gibt ein einfaches Perl-Skript, das Prüfsummen für jeden 1-MB-Teil des Standardeingabestroms erstellt. Es benötigt Crypt::RhashBindungen 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 
0
localhost

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.

0
Cristian Ciupitu

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() 
Was ist die Eingabe? Wie funktioniert das? Was macht der Benutzer von Schritt 1 bis Schritt * x *? Dies ist eine qualitativ schlechte Antwort, wie sie ist. Canadian Luke vor 9 Jahren 1
Bitte fügen Sie diesem Beitrag weitere Informationen hinzu (was jede Zeile macht usw. Fügen Sie einfach Kommentare hinzu). Ich habe in der LQP-Warteschlange "Looks Good" gedrückt, weil ich sehe, wie das Problem leicht behoben werden kann, aber wie es ist, ist es eine LQP. Frank vor 9 Jahren 0
@CanadianLuke, ich habe erklärt, wie man es benutzt. Cristian Ciupitu vor 9 Jahren 0