Calculer la somme md5 de chaque partie d'un flux de 1 Mo à partir d'un tuyau

3

Je souhaite effectuer des contrôles sur des fichiers volumineux et les diffuser sous unix / linux, et obtenir de nombreuses sommes de contrôle pour chaque grande partie d'un fichier / flux, tous les 1 Mo ou tous les 10 Mo.

Par exemple, j'ai une image disque, une image disque compressée et la copie du disque d'origine. Certaines parties des images peuvent être modifiées. Le disque a une capacité de 50 Go et environ 50000 blocs de 1 Mo. Donc, pour chaque fichier, je veux obtenir 50 000 md5sum ou sha1sums pour avoir un aperçu des modifications. Seul md5sum ne m'aidera pas à localiser le décalage de modification.

Cette tâche est facile pour une image disque non compressée, avec l’utilisation d’ ddoutil in forloop in bash avec des décalages informatiques et en sélectionnant (ignorant) chaque partie de fichier de 1 Mo. La même chose avec le disque:

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

Mais maintenant, je veux comparer une image compressée et une image non compressée sans la décompresser sur le disque. J'ai 7zdécompresseur qui peut décompresser l'image sur la sortie standard à grande vitesse, jusqu'à 150-200 Mo / s (options 7z e -so image.7z |). Mais que puis-je écrire après le |symbole pour obtenir md5sum de toutes les parties du fichier.

osgx
la source

Réponses:

2

Quelque chose de simple comme ce script Perl suffirait probablement.

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

Mettez ceci foo.plet invoquez-le comme perl foo.plà la fin de votre pipeline.

Kyle Jones
la source
Version cool, merci. Je viens de terminer ma propre utilisation Crypt::Rhash(md5 + sha1 + tigre - encore assez rapide). Vous pouvez changer mon code pour une meilleure lisibilité et style.
osgx
Et le script montre que mes images sont similaires à celles de mon disque dur, mais pas les mêmes. J'ai presque détruit 50 Go de données uniques.
osgx
7

séparé de coreutils (la valeur par défaut sur la plupart des distributions Linux) a une--filteroption que vous pouvez utiliser:

7z e -so image.7z | split -b 1000000 --filter=md5sum
Cristian Ciupitu
la source
Nifty. Je ne savais pas.
Kyle Jones
0

Il me semble que vous recherchez ce type d’ outil .

À partir du fichier Lisez-moi de BigSync:

Bigsync est un outil permettant de sauvegarder de manière incrémentielle un fichier volumineux vers une destination lente (média réseau ou NAS économique). Les cas les plus courants de bigsync sont les images de disque, les systèmes d’exploitation virtuels, les volumes chiffrés et les périphériques bruts.

Bigsync lira le fichier source en morceaux calculant des sommes de contrôle pour chacun. Il les comparera aux valeurs précédemment stockées pour le fichier de destination et écrasera les fragments modifiés si les sommes de contrôle sont différentes.

De cette façon, nous minimisons l'accès à un média cible lent, ce qui est le but de l'existence de bigsync.

Luis
la source
"Bigsync lira le fichier source en morceaux calculant des sommes de contrôle pour chacun" - cette partie est exacte, mais je ne souhaite rien modifier.
osgx
0

Il était facile d'écrire un petit hasher de 1 Mo à l'aide d' rhashoutils ( librhashbibliothèque). Il existe un script Perl simple qui crée des sommes de contrôle de chaque partie de 1 Mo du flux d'entrée standard. Il a besoin de Crypt::Rhashliaisons 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; 
}

Ce script du domaine public générera un décalage décimal, puis +, une taille de bloc, puis des sommes d’entrée md5 et sha1.

Par exemple, 2 Mo de zéros ont des sommes:

$ 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
osgx
la source
0

rsync fonctionne comme ceci, en calculant une somme de contrôle pour voir s’il existe des différences dans certaines parties du fichier avant d’envoyer quoi que ce soit.

Je ne sais pas si cela fonctionnerait bien avec des fichiers aussi volumineux, bien que je n’aie jamais entendu parler d’une limitation de la taille de fichier.

localhost
la source
0

Dirigez la sortie vers ce script Python 2, par exemple 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()
Cristian Ciupitu
la source
1
Quelle est l'entrée? Comment cela marche-t-il? Que fait l'utilisateur de l'étape 1 à l'étape x ? C'est une réponse de qualité médiocre telle quelle.
Canadien Luke
S'il vous plaît ajouter plus d'informations à ce poste (ce que chaque ligne fait, etc. Ajoutez juste des commentaires). J'ai cliqué sur Looks Good dans le LQP parce que je vois comment on pourrait le réparer facilement, mais comme c'est un LQP.
Jon
@CanadianLuke, j'ai expliqué comment l'utiliser.
Cristian Ciupitu