Bajo el supuesto de que la E / S de disco y la RAM libre es un cuello de botella (mientras que el tiempo de CPU no es la limitación), ¿existe una herramienta que pueda calcular múltiples resúmenes de mensajes a la vez?
Estoy particularmente interesado en calcular los resúmenes MD-5 y SHA-256 de archivos grandes (tamaño en gigabytes), preferiblemente en paralelo. Lo he intentado openssl dgst -sha256 -md5
, pero solo calcula el hash usando un algoritmo.
Pseudocódigo para el comportamiento esperado:
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
fuente
fuente
for i in file1 file2 …; do sha256 "$i"& md5sum "$i"; done
for i in file1 file2 …; do tee < "$i" >(sha256sum) | md5sum ; done
luego debe agregar un código adicional para marcar el nombre del archivo, ya que se envía como entrada estándar amd5sum
ysha256sum
.Respuestas:
Retirar
pee
("tee standard input to pipes
") demoreutils
. Esto es básicamente equivalente altee
comando de Marco , pero un poco más simple de escribir.fuente
pee
tiene la mejor interfaz, una comparación de tiempo con otras herramientas se puede encontrar en esta publicación que también muestra una herramienta Python de subprocesos múltiples.moreutils
entraGNU parallel
en conflicto con mi sistema Debian ... sin embargo, es bueno saber que existe esa herramienta.aptitude
, no me deja tener los dos paquetes al mismo tiempo).moreutils-parallel
nombre para evitar el conflicto.Puede usar un
for
bucle para recorrer los archivos individuales y luego usarlotee
combinado con la sustitución de procesos (funciona en Bash y Zsh, entre otros) para canalizar a diferentes summers de verificación.Ejemplo:
También puede usar más de dos summers de verificación:
Esto tiene la desventaja de que los summers de verificación no conocen el nombre del archivo, ya que se pasa como entrada estándar. Si eso no es aceptable, debe emitir los nombres de archivo manualmente. Ejemplo completo:
fuente
*sum
familia de herramientas, esta expresión sed podría usarse en su lugar:sed "s;-\$;${file//;/\\;};
(reemplazó el final-
por el nombre del archivo, pero asegúrese de que el nombre del archivo se escape correctamente).zsh
. En ksh93 y bash, la salida de sha256sum va a md5sum. Usted querrá:{ tee < "$file" >(sha256sum >&3) | md5sum; } 3>&1
. Consulte unix.stackexchange.com/q/153896/22565 para ver el problema inverso.Es una pena que la utilidad openssl no acepte múltiples comandos de resumen; Supongo que ejecutar el mismo comando en varios archivos es un patrón de uso más común. FWIW, la versión de la utilidad openssl en mi sistema (Mepis 11) solo tiene comandos para sha y sha1, no ninguna de las otras variantes de sha. Pero tengo un programa llamado sha256sum, así como md5sum.
Aquí hay un programa simple de Python, dual_hash.py, que hace lo que quieres. Un tamaño de bloque de 64k parece ser óptimo para mi máquina (Intel Pentium 4 2.00GHz con 2G de RAM), YMMV. Para archivos pequeños, su velocidad es aproximadamente la misma que ejecutar md5sum y sha256sum en sucesión. Pero para archivos más grandes es significativamente más rápido. Por ejemplo, en un archivo de bytes de 1967063040 (una imagen de disco de una tarjeta SD llena de archivos mp3), md5sum + sha256sum toma alrededor de 1m44.9s, dual_hash.py toma 1m0.312s.
dual_hash.py
Supongo que una versión C / C ++ de este programa sería un poco más rápida, pero no mucho, ya que la mayoría del trabajo lo realiza el módulo hashlib, que está escrito en C (o C ++). Y como notó anteriormente, el cuello de botella para archivos grandes es la velocidad de E / S.
fuente
md5sum
ysha256sum
combinada (4.7s + 14.2s vs 18.7s para este script Python, archivo en caché; 33.6s para la ejecución en frío). 64KiB vs 1MiB no cambió la situación. Con el código comentado, 5.1s se gastaron en md5 (n = 3), 14.6s en sha1 (n = 3). Probado en un i5-460M con 8GB de RAM. Supongo que esto podría mejorarse aún más utilizando más hilos.digests
solo procesa un único archivo en cada llamada. Entonces, incluso si lo llamó en un bucle, creará nuevos contextos md5 y sha en cada llamada. FWIW, puedes disfrutar de mi hash SHA-256 reanudable .Siempre puedes usar algo como GNU paralelo :
Alternativamente, simplemente ejecute uno de los dos en segundo plano:
O guarde la salida en diferentes archivos y ejecute varios trabajos en segundo plano:
Que pondrá en marcha la mayor cantidad
md5sum
ysha256sum
casos que tiene archivos y todos ellos se ejecutarán en paralelo, el ahorro de su producción a los nombres de los archivos correspondientes. Sin embargo, con cuidado, esto puede volverse pesado si tiene muchos archivos.fuente
Por curiosidad sobre si un script Python multihilo reduciría el tiempo de ejecución, creé este
digest.py
script que usathreading.Thread
,threading.Queue
yhashlib
para calcular los hashes para múltiples archivos.La implementación de Python multiproceso es de hecho un poco más rápida que la que se usa
pee
con coreutils. Java por otro lado es ... meh. Los resultados están disponibles en este mensaje de confirmación :La salida hash es compatible con la salida producida por coreutils. Como la longitud depende del algoritmo de hash, esta herramienta no lo imprime. Uso (para comparación,
pee
también se agregó):fuente
pee "openssl sha256" "openssl md5" < file
, pero, sinceramente, lo intenté y no superó digest.py. Sin embargo, redujo la brecha.Jacksum es una utilidad gratuita e independiente de la plataforma para computar y verificar sumas de verificación, CRC y hashes (resúmenes de mensajes), así como marcas de tiempo de archivos. ( Extraído de la página de manual de jacksum )
Es compatible con archivos grandes, puede procesar archivos de hasta 8 Exabytes (= 8,000,000,000 Gigabytes), presupone su sistema operativo, respectivamente, su sistema de archivos también es compatible con archivos grandes. (Extraído de http://www.jonelo.de/java/jacksum/ )
Ejemplo de uso:
Salida de muestra:
En ubuntu, ejecute el comando
apt-get install jacksum
para obtenerlo.Alternativamente, los códigos fuente están disponibles en
fuente