Mesclar vários arquivos com base no md5sum

1

Eu tenho um arquivo data.txt, que foi dividido em fragmentos. Eu preciso combinar corretamente fragmentos de arquivos para que o arquivo original foi criado data.txt. Eu não sei qual procedimento faz isso, porque os nomes dos fragmentos não têm uma hierarquia. Mas eu tenho um arquivo md5sum data.txt (que lista os fragmentos). Como posso usar o arquivo md5sum para restaurar o arquivo inteiro de seus fragmentos?

    
por lukassz 14.08.2015 / 12:38

3 respostas

1

perl -MAlgorithm::Combinatorics=permutations \
  -le '$i=permutations(\@ARGV); while ($p=$i->next) { $n++; print "combo$n @$p" }' frag1 frag2 frag3 frag4 \
| while read out a b c d; do cat $a $b $c $d > $out; md5 $out; done

Ou md5sum em vez de md5 se você tiver as ferramentas GNU.

    
por 14.08.2015 / 18:47
0

Quantos fragmentos existem? Parece que você teria que tentar todas as permutações dos fragmentos (ou até chegar ao ponto certo), portanto, mesmo a solução do problema para uma quantidade relativamente pequena de fragmentos resultará em uma grande quantidade de trabalho.

    
por 14.08.2015 / 14:17
0

Conhecer a soma de verificação de uma parte não ajuda a calcular a soma de verificação do todo, então você terá que calcular a soma de verificação de todas as permutações possíveis até encontrar a correta. Se você tem partes n , existem n ! (fatorial de n ) permutações, e se todas são igualmente prováveis você terá que processar n ! / 2 em média até encontrar o caminho certo.

Quando você precisar calcular a soma de verificação de várias seqüências com o mesmo prefixo, poderá economizar tempo armazenando o estado interno da função MD5. Por exemplo, com três partes (X, Y, Z), você precisaria calcular MD5 (X + Y + Z), MD5 (X + Z + Y), MD5 (Y + X + Z), MD5 (Y + Z + X), MD5 (Z + X + Y) e MD5 (Z + Y + X). Se você iniciar o cálculo de MD5 (X,…), duplique o estado e conclua o cálculo para os dois sufixos Y + Z e Z + Y. Mas você precisa do estado interno para isso, não para a saída, e a maioria das ferramentas não dá acesso ao estado interno.

O hashlib do Python fornece um método copy para copiar o estado interno de uma função hash. Ele também tem um iterador para enumerar permutações em sua biblioteca padrão.

#!/usr/bin/env python2
import hashlib, itertools, sys

def look_for_permutation(goal, filenames):
    n = len(filenames)
    files = map(open, filenames)
    previous = map(lambda _: None, filenames)
    states = [hashlib.md5()] + [None] * (n-2)
    for current in itertools.permutations(files):
        i = 0
        while current[i] == previous[i]:
            i += 1
        state = states[i].copy()
        for f in current[i:n-2]:
            state.update(f.read())
            i += 1
            states[i] = state.copy()
            f.seek(0)
        state.update(current[n-2].read())
        current[n-2].seek(0)
        state.update(current[n-1].read())
        if state.hexdigest() == goal:
            return current
        current[n-1].seek(0)
        previous = current
    return None

if __name__ == '__main__':
    result = look_for_permutation(sys.argv[1], sys.argv[2:])
    if result:
        for f in result: print f.name
        sys.exit(0)
    else:
        sys.exit(1)

Este script otimiza os cálculos de hash, mas lê o conteúdo do arquivo repetidamente. Se o conteúdo dos arquivos se encaixa na memória, você pode torná-lo um pouco mais rápido, carregando os arquivos de uma vez por todas.

    
por 15.08.2015 / 02:25