Unter der Annahme, dass Festplatten-E / A und freier RAM ein Engpass sind (während die CPU-Zeit keine Einschränkung darstellt), gibt es ein Tool, mit dem mehrere Message Digests gleichzeitig berechnet werden können?
Ich interessiere mich besonders für die parallele Berechnung der MD-5- und SHA-256-Digests großer Dateien (Größe in Gigabyte). Ich habe es versucht openssl dgst -sha256 -md5
, aber es berechnet nur den Hash mit einem Algorithmus.
Pseudocode für das erwartete Verhalten:
for each block:
for each algorithm:
hash_state[algorithm].update(block)
for each algorithm:
print algorithm, hash_state[algorithm].final_hash()
shell-script
hashsum
parallelism
Lekensteyn
quelle
quelle
for i in file1 file2 …; do sha256 "$i"& md5sum "$i"; done
for i in file1 file2 …; do tee < "$i" >(sha256sum) | md5sum ; done
Dann müssen Sie zusätzlichen Code hinzufügen, um den Dateinamen zu markieren, da er als Standardeingabe anmd5sum
und gesendet wirdsha256sum
.Antworten:
Auschecken
pee
("tee standard input to pipes
") vonmoreutils
. Dies entspricht im Wesentlichen demtee
Befehl von Marco , ist jedoch etwas einfacher zu tippen.quelle
pee
Hat die beste Oberfläche, einen Zeitvergleich mit anderen Tools finden Sie in diesem Beitrag, der auch ein Multithread-Python-Tool demonstriert.moreutils
Konflikte mitGNU parallel
meinem Debian-System ... es ist jedoch gut zu wissen, dass es ein solches Tool gibt.aptitude
ich kann nicht beide Pakete gleichzeitig haben).moreutils-parallel
Namen, um den Konflikt zu vermeiden.Sie können eine
for
Schleife verwenden, um die einzelnen Dateientee
zu durchlaufen, und dann in Kombination mit der Prozessersetzung (funktioniert unter anderem in Bash und Zsh) die Pipe-Funktion für verschiedene Prüfsummen verwenden.Beispiel:
Sie können auch mehr als zwei Prüfsummen verwenden:
Dies hat den Nachteil, dass die Prüfsummen den Dateinamen nicht kennen, da er als Standardeingabe übergeben wird. Wenn dies nicht akzeptabel ist, müssen Sie die Dateinamen manuell eingeben. Vollständiges Beispiel:
quelle
*sum
Familie von Werkzeugen, könnte dies sed Ausdruck stattdessen verwendet werden:sed "s;-\$;${file//;/\\;};
(ersetzt die nachgestellten-
durch die Dateinamen, aber sicher , dass der Dateiname richtig übersetzt wird).zsh
. In ksh93 und bash geht die Ausgabe von sha256sum nach md5sum. Sie wollen:{ tee < "$file" >(sha256sum >&3) | md5sum; } 3>&1
. Informationen zum umgekehrten Problem finden Sie unter unix.stackexchange.com/q/153896/22565 .Schade, dass das Dienstprogramm openssl keine Befehle für mehrere Digests akzeptiert. Ich denke, der gleiche Befehl für mehrere Dateien ist ein häufigeres Verwendungsmuster. FWIW, die Version des Dienstprogramms openssl auf meinem System (Mepis 11) enthält nur Befehle für sha und sha1, keine der anderen sha-Varianten. Aber ich habe ein Programm namens sha256sum sowie md5sum.
Hier ist ein einfaches Python-Programm, dual_hash.py, das macht, was Sie wollen. Eine Blockgröße von 64 KB scheint für meinen Computer (Intel Pentium 4 2.00 GHz mit 2 G RAM) und YMMV optimal zu sein. Bei kleinen Dateien entspricht die Geschwindigkeit in etwa der von md5sum und sha256sum nacheinander. Bei größeren Dateien ist dies jedoch erheblich schneller. Beispiel: Auf einer 1967063040-Byte-Datei (ein Festplatten-Image einer SD-Karte mit MP3-Dateien) dauert md5sum + sha256sum ungefähr 1m44.9s, dual_hash.py dauert 1m0.312s.
dual_hash.py
Ich nehme an, eine C / C ++ Version dieses Programms wäre ein wenig schneller sein, aber nicht viel, da die meiste Arbeit wird von der hashlib Modul erfolgen, das ist in C geschrieben (oder C ++). Wie Sie bereits erwähnt haben, liegt der Engpass bei großen Dateien in der E / A-Geschwindigkeit.
quelle
md5sum
undsha256sum
kombiniert (4,7 s + 14,2 s gegenüber 18,7 s für dieses Python-Skript, Datei im Cache; 33,6 s für den Kaltlauf). 64KiB vs 1MiB haben die Situation nicht verändert. Mit kommentiertem Code wurden 5,1 s für md5 (n = 3) und 14,6 s für sha1 (n = 3) ausgegeben. Getestet auf einem i5-460M mit 8 GB RAM. Ich denke, dass dies durch die Verwendung von mehr Threads weiter verbessert werden könnte.digests
verarbeitet nur eine einzelne Datei bei jedem Aufruf. Selbst wenn Sie es in einer Schleife aufrufen, werden bei jedem Aufruf neue md5 & sha-Kontexte erstellt. FWIW, Sie können meinen wiederaufnehmbaren SHA-256-Hash genießen .Sie könnten immer so etwas wie GNU parallel verwenden :
Alternativ können Sie auch einfach eine der beiden im Hintergrund ausführen:
Oder speichern Sie die Ausgabe in verschiedenen Dateien und führen Sie mehrere Jobs im Hintergrund aus:
Dadurch werden so viele
md5sum
undsha256sum
Instanzen gestartet, wie Sie über Dateien verfügen, und alle werden parallel ausgeführt, und ihre Ausgabe wird unter den entsprechenden Dateinamen gespeichert. Achtung, dies kann sehr schwer werden, wenn Sie viele Dateien haben.quelle
Aus Neugier, ob ein Multithread-Python-Skript die Laufzeit verkürzen würde, habe ich dieses
digest.py
Skript erstelltthreading.Thread
, das Hashes für mehrere Dateien verwendetthreading.Queue
undhashlib
berechnet.Die Multithread-Python-Implementierung ist in der Tat etwas schneller als die Verwendung
pee
mit coreutils. Java auf der anderen Seite ist ... meh. Die Ergebnisse sind in dieser Festschreibungsnachricht verfügbar :Die Hash-Ausgabe ist mit der Ausgabe von coreutils kompatibel. Da die Länge vom Hashing-Algorithmus abhängt, wird sie von diesem Tool nicht gedruckt. Verwendung (zum Vergleich
pee
wurde auch hinzugefügt):quelle
pee "openssl sha256" "openssl md5" < file
, aber ehrlich gesagt habe ich es einfach versucht und es hat Digest.py nicht übertroffen. Es verengte jedoch die Lücke.Jacksum ist ein kostenloses und plattformunabhängiges Dienstprogramm zum Berechnen und Überprüfen von Prüfsummen, CRCs und Hashes (Message Digests) sowie Zeitstempeln von Dateien. (Auszug aus der Jacksum-Manpage )
Es unterstützt große Dateien, es kann Dateigrößen von bis zu 8 Exabyte (= 8.000.000.000 Gigabyte) verarbeiten, vorausgesetzt, Ihr Betriebssystem bzw. Ihr Dateisystem unterstützt große Dateien. (Auszug aus http://www.jonelo.de/java/jacksum/ )
Anwendungsbeispiel:
Beispielausgabe:
Führen Sie unter Ubuntu den Befehl aus
apt-get install jacksum
, um ihn abzurufen .Alternativ stehen Quellcodes unter zur Verfügung
quelle