Compute md5sum de cada parte de 1MB do stream do pipe

2

Eu quero fazer checksum de arquivos grandes e transmitir em unix / linux, e eu quero obter muitas somas de verificação de cada grande parte do arquivo / stream, a cada 1 MB ou a cada 10MB.

Por exemplo, tenho imagem de disco, imagem de disco compactada e a cópia do disco original. Algumas partes das imagens podem ser modificadas. O disco é de 50 GB e há cerca de 50000 de blocos de 1 MB. Portanto, para cada arquivo, quero obter 50 000 md5sum ou sha1sums para obter uma visão geral das modificações. O md5sum único não me ajudará a localizar o deslocamento de modificação.

Essa tarefa é fácil para a imagem de disco não compactada, com o uso da ferramenta dd em for loop no bash com os deslocamentos de computação e a seleção (ignorar) de cada parte de 1 MB do arquivo. O mesmo com o disco:

for a in 'seq 1 50000'; do echo -n "$a: "; dd if=image.src bs=1M count=1 skip=$a | md5sum; done

Mas agora quero comparar a imagem compactada e a não compactada sem descompactá-la no disco. Eu tenho 7z unpacker que pode descompactar a imagem para stdout com alta velocidade, até 150-200 MB / s (opções 7z e -so image.7z | ). Mas o que posso escrever depois do símbolo | para obter o md5sum de todas as partes do arquivo.

    
por osgx 20.05.2014 / 00:36

6 respostas

2

Algo simples como este script Perl provavelmente seria suficiente.

$amount = 1_000_000;
while (read(STDIN, $buffer, $amount) > 0) {
    open MD5, "|md5";
    print MD5 $buffer;
    close MD5;
}

Coloque isso em foo.pl e invoque-o como perl foo.pl no final do seu pipeline.

    
por 20.05.2014 / 01:39
6

dividido do coreutils (o padrão na maioria das distribuições Linux) tem uma opção --filter que você pode usar:

7z e -so image.7z | split -b 1000000 --filter=md5sum
    
por 20.05.2014 / 04:13
0

Parece-me que você está procurando por esse tipo de ferramenta .

Do arquivo Leia-me do BigSync:

Bigsync is a tool to incrementally backup a single large file to a slow destination (think network media or a cheap NAS). The most common cases for bigsync are disk images, virtual OSes, encrypted volumes and raw devices.

Bigsync will read the source file in chunks calculating checksums for each one. It will compare them with previously stored values for the destination file and overwrite changed chunks if checksums differ.

This way we minimize the access to a slow target media which is the whole point of bigsync's existence.

    
por 20.05.2014 / 01:21
0

Foi fácil escrever uma pequena hasher de 1 MB usando rhash tools ( librhash library). Existe um script perl simples que cria somas de verificação de cada parte de 1MB do fluxo de entrada padrão. Ele precisa de Crypt::Rhash de ligações de 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; 
}

Esse script de domínio público gerará o deslocamento decimal, em seguida, + , depois o tamanho do bloco e, em seguida, as somas md5 e sha1 da entrada.

Por exemplo, 2 MB de zeros tem somas:

$ 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
    
por 20.05.2014 / 01:39
0

rsync funciona assim, calculando uma soma de verificação para ver se há diferenças em partes do arquivo antes de enviar qualquer coisa.

Não tenho certeza de como isso funcionaria com arquivos tão grandes, embora eu nunca tenha ouvido falar de alguma limitação de tamanho de arquivo.

    
por 20.05.2014 / 02:46
0

Canalize a saída para esse script do Python 2, por exemplo, 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()
    
por 20.05.2014 / 03:37