Uma solução portátil Python 2/3
Para calcular uma soma de verificação (md5, sha1 etc.), você deve abrir o arquivo no modo binário, porque você somará valores de bytes:
Para ser portátil py27 / py3, você deve usar os io
pacotes, assim:
import hashlib
import io
def md5sum(src):
md5 = hashlib.md5()
with io.open(src, mode="rb") as fd:
content = fd.read()
md5.update(content)
return md5
Se seus arquivos forem grandes, convém ler o arquivo em pedaços para evitar armazenar todo o conteúdo do arquivo na memória:
def md5sum(src, length=io.DEFAULT_BUFFER_SIZE):
md5 = hashlib.md5()
with io.open(src, mode="rb") as fd:
for chunk in iter(lambda: fd.read(length), b''):
md5.update(chunk)
return md5
O truque aqui é usar a iter()
função com uma sentinela (a sequência vazia).
O iterador criado neste caso chamará o [a função lambda] sem argumentos para cada chamada ao seu next()
método; se o valor retornado for igual a sentinel, StopIteration
será aumentado; caso contrário, o valor será retornado.
Se seus arquivos forem realmente grandes, talvez você também precise exibir informações de progresso. Você pode fazer isso chamando uma função de retorno de chamada que imprime ou registra a quantidade de bytes calculados:
def md5sum(src, callback, length=io.DEFAULT_BUFFER_SIZE):
calculated = 0
md5 = hashlib.md5()
with io.open(src, mode="rb") as fd:
for chunk in iter(lambda: fd.read(length), b''):
md5.update(chunk)
calculated += len(chunk)
callback(calculated)
return md5