Ricerca e stampa MD5checksum (Prova pratica 21-01-2015)

From Sistemi Operativi
Jump to navigation Jump to search

Scrivere un programma python o uno script bash che scandisca il sottoalbero relativo alle directory passate come parametri (o alla direcotry corrente se non ci sono parametri) e fornisca in output l'elenco dei file che hanno la stessa somma MD5 (i.e. l'output del comando md5sum). In output ogni riga deve mostrare un elenco di pathname realtivi a file che hanno la stessa somma MD5 (che quindi sono molto molto probabilmente uguali)

Soluzione di Stefano Zaniboni

#!/usr/bin/env python3
from collections import defaultdict
import hashlib
import os
import sys


def md5checksum(filepath):
    with open(filepath, "rb") as afile:
        m = hashlib.md5()
        data = afile.read()
        m.update(data)
    return m.hexdigest()


def calculate_checksums(search_dir):
    checksums = defaultdict(list)

    for root, dirs, files in os.walk(search_dir):
        for filename in files:
            path = os.path.join(root, filename)
            checksum = md5checksum(path)
            checksums[checksum].append(path)
    return checksums


def display_equal_files(checksums):
    for checksum, paths in checksums.items():
        if len(paths) > 1:
            print("MD5 sum: {}".format(checksum))
            for path in paths:
                print("    {}".format(path))


if __name__ == "__main__":
    search_dir = sys.argv[1]
    checksums = calculate_checksums(search_dir)
    display_equal_files(checksums)

Ringrazio per l'aiuto nella ricerca dei file con stesso MD5 la comunità di stackoverflow

Soluzione Blissett

<source lang="bash">

  1. ! /bin/bash

if $#=1 then if -d $1 then cd $1 else echo "Usage: `basename $0` directory" exit $? fi fi

tmp="" indice=0 find=0 declare -a array declare -a m5s

for file in `find ./ -type f` do tmp=`md5sum $file | awk '{print $1}'` for i in ${!m5s[@]} do if [[ "${m5s[$i]}" = "$tmp" ]] then array[$i]="${array[$i]}`basename $file`; " find=1 break fi done

if $find = 0 then m5s[$indice]=$tmp array[$indice]="`basename $file`; " indice=$(($indice + 1)) fi find=0 done

for i in ${!array[@]} do echo "${array[$i]}" done