Sob a suposição de que a E / S do disco e a RAM livre são um gargalo (embora o tempo da CPU não seja a limitação), existe uma ferramenta que pode calcular vários resumos de mensagens de uma só vez?
Estou particularmente interessado em calcular os resumos MD-5 e SHA-256 de arquivos grandes (tamanho em gigabytes), de preferência em paralelo. Eu tentei openssl dgst -sha256 -md5
, mas ele só calcula o hash usando um algoritmo.
Pseudo-código para o comportamento 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
fonte
fonte
for i in file1 file2 …; do sha256 "$i"& md5sum "$i"; done
for i in file1 file2 …; do tee < "$i" >(sha256sum) | md5sum ; done
Depois, adicione um código adicional para marcar o nome do arquivo, porque ele é enviado como entrada padrão paramd5sum
esha256sum
.Respostas:
Confira
pee
("tee standard input to pipes
") emmoreutils
. Isso é basicamente equivalente aotee
comando de Marco , mas um pouco mais simples de digitar.fonte
pee
tem a melhor interface, uma comparação de tempo com outras ferramentas pode ser encontrada neste post, que também demonstra uma ferramenta Python multiencadeada.moreutils
conflitosGNU parallel
no meu sistema Debian ... é bom saber que existe uma ferramenta desse tipo.aptitude
, não me deixa ter os dois pacotes ao mesmo tempo).moreutils-parallel
nome para evitar o conflito.Você pode usar um
for
loop para percorrer os arquivos individuais e, em seguida, usartee
combinado com a substituição do processo (funciona no Bash e no Zsh entre outros) para canalizar para diferentes verões de verificação.Exemplo:
Você também pode usar mais de dois verões de verificação:
Isso tem a desvantagem de que os verificadores de verificação não sabem o nome do arquivo, porque é passado como entrada padrão. Se isso não for aceitável, você deverá emitir os nomes dos arquivos manualmente. Exemplo completo:
fonte
*sum
família de ferramentas, essa expressão sed poderia ser usada:sed "s;-\$;${file//;/\\;};
(substituiu a trilha-
pelo nome do arquivo, mas assegure-se de que o nome do arquivo seja escapado adequadamente).zsh
. No ksh93 e no bash, a saída do sha256sum vai para o md5sum. Você vai querer:{ tee < "$file" >(sha256sum >&3) | md5sum; } 3>&1
. Consulte unix.stackexchange.com/q/153896/22565 para obter o problema inverso.É uma pena que o utilitário openssl não aceite vários comandos digest; Eu acho que executar o mesmo comando em vários arquivos é um padrão de uso mais comum. FWIW, a versão do utilitário openssl no meu sistema (Mepis 11) possui apenas comandos para sha e sha1, não nenhuma das outras variantes do sha. Mas eu tenho um programa chamado sha256sum, assim como md5sum.
Aqui está um simples programa Python, dual_hash.py, que faz o que você deseja. Um tamanho de bloco de 64k parece ser ideal para minha máquina (Intel Pentium 4 2.00GHz com 2G de RAM), YMMV. Para arquivos pequenos, sua velocidade é aproximadamente a mesma que executar md5sum e sha256sum em sucessão. Mas para arquivos maiores é significativamente mais rápido. Por exemplo, em um arquivo de 1967063040 bytes (uma imagem de disco de um cartão SD cheio de arquivos mp3), md5sum + sha256sum leva cerca de 1m44,9s, dual_hash.py leva 1m0,312s.
dual_hash.py
Suponho que uma versão C / C ++ deste programa seria um pouco mais rápido, mas não muito, já que a maior parte do trabalho está sendo feito pelo módulo hashlib, que é escrito em C (ou C ++). E, como você observou acima, o gargalo para arquivos grandes é a velocidade de E / S.
fonte
md5sum
esha256sum
combinada (4.7s + 14.2s vs 18.7s para este script Python, arquivo em cache; 33.6s para execução a frio). 64KiB vs 1MiB não mudou a situação. Com o código comentado, 5,1s foram gastos em md5 (n = 3), 14,6s em sha1 (n = 3). Testado em um i5-460M com 8 GB de RAM. Eu acho que isso poderia ser melhorado usando mais threads.digests
processa apenas um único arquivo em cada chamada. Portanto, mesmo se você o chamar em loop, criará novos contextos md5 e sha em cada chamada. FWIW, você pode desfrutar do meu hash SHA-256 recuperável .Você sempre pode usar algo como o GNU paralelo :
Como alternativa, basta executar um dos dois em segundo plano:
Ou salve a saída em arquivos diferentes e execute vários trabalhos em segundo plano:
Que vai lançar o maior número
md5sum
esha256sum
casos que você tem arquivos e todos eles serão executados em paralelo, poupando sua produção para os nomes de arquivos correspondentes. Cuidado, porém, isso pode ficar pesado se você tiver muitos arquivos.fonte
Por curiosidade se um script multi-threaded Python iria reduzir o tempo de execução, eu criei este
digest.py
script que usosthreading.Thread
,threading.Queue
ehashlib
para calcular os hashes para vários arquivos.A implementação Python multiencadeada é realmente um pouco mais rápida do que usar
pee
com coreutils. Java, por outro lado, é ... meh. Os resultados estão disponíveis nesta mensagem de confirmação :A saída de hash é compatível com a saída produzida por coreutils. Como o comprimento depende do algoritmo de hash, essa ferramenta não o imprime. Uso (para comparação,
pee
também foi adicionado):fonte
pee "openssl sha256" "openssl md5" < file
, mas, honestamente, eu apenas tentei, e não superou digest.py. Ele diminuiu a diferença, no entanto.Jacksum é um utilitário gratuito e independente de plataforma para computação e verificação de somas de verificação, CRCs e hashes (resumos de mensagens), bem como registros de data e hora de arquivos. (extraído da página do manual jacksum )
Ele reconhece arquivos grandes, pode processar tamanhos de arquivos de até 8 Exabytes (= 8.000.000.000 Gigabytes), pressupondo o sistema operacional, respectivamente, o sistema de arquivos também reconhece arquivos grandes. (extraído de http://www.jonelo.de/java/jacksum/ )
Exemplo de uso:
Saída de amostra:
No ubuntu, execute o comando
apt-get install jacksum
para obtê-lo.Como alternativa, os códigos-fonte estão disponíveis em
fonte