Zakładając, że dyskowe operacje we / wy i wolna pamięć RAM stanowią wąskie gardło (choć czas procesora nie jest ograniczeniem), czy istnieje narzędzie, które może obliczyć wiele skrótów wiadomości jednocześnie?
Szczególnie interesuje mnie obliczanie skrótów MD-5 i SHA-256 dużych plików (rozmiar w gigabajtach), najlepiej równolegle. Próbowałem openssl dgst -sha256 -md5
, ale oblicza skrót tylko przy użyciu jednego algorytmu.
Pseudokod oczekiwanego zachowania:
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
źródło
źródło
for i in file1 file2 …; do sha256 "$i"& md5sum "$i"; done
for i in file1 file2 …; do tee < "$i" >(sha256sum) | md5sum ; done
Następnie musisz dodać dodatkowy kod, aby oznaczyć nazwę pliku, ponieważ jest on wysyłany jako standardowe wejście domd5sum
isha256sum
.Odpowiedzi:
Sprawdź
pee
(„tee standard input to pipes
”) odmoreutils
. Jest to w zasadzie równoważne poleceniu Marcotee
, ale nieco prostsze w pisaniu.źródło
pee
ma najlepszy interfejs, porównanie czasu z innymi narzędziami można znaleźć w tym poście, który pokazuje również wielowątkowe narzędzie Python.moreutils
konflikty zGNU parallel
moim systemem Debian… dobrze wiedzieć, że istnieje takie narzędzie.aptitude
Nie pozwala mi mieć obu pakietów jednocześnie).moreutils-parallel
nazwa pozwalająca uniknąć konfliktu.Możesz użyć
for
pętli do zapętlenia poszczególnych plików, a następnie użyć wtee
połączeniu z podstawieniem procesu (działa między innymi w Bash i Zsh), aby przesłać do różnych sum kontrolnych.Przykład:
Możesz także użyć więcej niż dwóch sum kontrolnych:
Ma to tę wadę, że sumy kontrolne nie znają nazwy pliku, ponieważ jest on przekazywany jako standardowe wejście. Jeśli to nie jest dopuszczalne, musisz ręcznie wysłać nazwy plików. Kompletny przykład:
źródło
*sum
rodziną narzędzi, można zamiast tego użyć wyrażenia sed:sed "s;-\$;${file//;/\\;};
(zastąpiono znak końcowy-
nazwą pliku, ale należy się upewnić, że nazwa pliku zostanie poprawnie zmieniona).zsh
. W ksh93 i bash wyjście sha256sum przechodzi do md5sum. Będziemy chcieli:{ tee < "$file" >(sha256sum >&3) | md5sum; } 3>&1
. Zobacz unix.stackexchange.com/q/153896/22565, aby uzyskać informacje o odwrotnym problemie.Szkoda, że narzędzie openssl nie akceptuje wielu poleceń skrótu; Wydaje mi się, że wykonywanie tego samego polecenia na wielu plikach jest bardziej powszechnym wzorcem użycia. FWIW, wersja narzędzia openssl w moim systemie (Mepis 11) zawiera tylko polecenia sha i sha1, a nie inne warianty sha. Ale mam program o nazwie sha256sum, a także md5sum.
Oto prosty program w języku Python, dual_hash.py, który robi to, co chcesz. Rozmiar bloku 64k wydaje się być optymalny dla mojego komputera (Intel Pentium 4 2,00 GHz z 2 GB pamięci RAM), YMMV. W przypadku małych plików jego prędkość jest w przybliżeniu taka sama, jak uruchamianie kolejno md5sum i sha256sum. Ale w przypadku większych plików jest to znacznie szybsze. Np. W pliku bajtów 1967063040 (obraz dysku z kartą SD pełną plików mp3), md5sum + sha256sum zajmuje około 1m44,9s, dual_hash.py zajmuje 1m0,312s.
dual_hash.py
Przypuszczam, C / C ++ wersja tego programu byłoby trochę szybciej, ale nie za dużo, ponieważ większość prac jest wykonywana przez moduł hashlib, który jest napisany w C (lub C ++). Jak wspomniano powyżej, wąskim gardłem w przypadku dużych plików jest szybkość operacji we / wy.
źródło
md5sum
isha256sum
połączoną (4,7 s + 14,2 s vs 18,7 s dla tego skryptu Python, plik w pamięci podręcznej; 33,6 s dla zimnego uruchomienia). 64KiB vs 1MiB nie zmieniło sytuacji. Z komentarzem do kodu 5.1s wydano na md5 (n = 3), a 14,6s na sha1 (n = 3). Testowane na i5-460M z 8 GB pamięci RAM. Myślę, że można to jeszcze poprawić, używając więcej wątków.digests
przetwarza tylko jeden plik dla każdego połączenia. Więc nawet jeśli wywołałeś to w pętli, utworzy nowe konteksty md5 i sha przy każdym wywołaniu. FWIW, możesz cieszyć się moim wznawiającym się skrótem SHA-256 .Zawsze możesz użyć czegoś takiego jak GNU równolegle :
Alternatywnie, po prostu uruchom jeden z dwóch w tle:
Lub zapisz dane wyjściowe w różnych plikach i uruchom wiele zadań w tle:
Spowoduje to uruchomienie dowolnej liczby instancji
md5sum
i ich liczby, asha256sum
wszystkie będą działać równolegle, zapisując dane wyjściowe pod odpowiednimi nazwami plików. Ostrożnie, może to być ciężkie, jeśli masz wiele plików.źródło
Z ciekawości czy wielowątkowy scenariusz Python by ograniczyć czas pracy, stworzyłem ten
digest.py
skrypt, który używathreading.Thread
,threading.Queue
ahashlib
do obliczenia wartości mieszania dla wielu plików.Wielowątkowa implementacja Pythona jest rzeczywiście nieco szybsza niż w
pee
przypadku coreutils. Z drugiej strony Java to ... meh. Wyniki są dostępne w tym komunikacie zatwierdzenia :Dane wyjściowe mieszania są zgodne z danymi wyjściowymi produkowanymi przez coreutils. Ponieważ długość zależy od algorytmu mieszania, narzędzie to nie drukuje. Zastosowanie (dla porównania
pee
również zostało dodane):źródło
pee "openssl sha256" "openssl md5" < file
, ale, szczerze mówiąc, właśnie tego spróbowałem i nie pobiło ono straw.py. Jednak zmniejszył lukę.Jacksum to bezpłatne i niezależne od platformy narzędzie do obliczania i weryfikacji sum kontrolnych, CRC i skrótów (skrótów wiadomości), a także znaczników czasu plików. (fragment strony podręcznika użytkownika jacksum )
Jest świadomy dużych plików, może przetwarzać pliki o wielkości do 8 eksabajtów (= 8 000 000 000 gigabajtów), zakładając, że twój system operacyjny lub twój system plików też jest świadomy dużych plików. (fragment z http://www.jonelo.de/java/jacksum/ )
Przykład użycia:
Przykładowe dane wyjściowe:
Na Ubuntu, uruchom polecenie,
apt-get install jacksum
aby go zdobyć.Alternatywnie, kody źródłowe są dostępne pod adresem
źródło