Existe uma maneira que é bastante ineficiente de memória .
único arquivo:
import hashlib
def file_as_bytes(file):
with file:
return file.read()
print hashlib.md5(file_as_bytes(open(full_path, 'rb'))).hexdigest()
lista de arquivos:
[(fname, hashlib.md5(file_as_bytes(open(fname, 'rb'))).digest()) for fname in fnamelst]
Lembre-se, porém, que o MD5 é conhecido como quebrado e não deve ser usado para nenhuma finalidade, pois a análise de vulnerabilidade pode ser realmente complicada, e é impossível analisar qualquer possível uso futuro ao qual seu código possa ser usado para problemas de segurança. IMHO, ele deve ser totalmente removido da biblioteca para que todos que o usem sejam forçados a atualizar. Então, aqui está o que você deve fazer:
[(fname, hashlib.sha256(file_as_bytes(open(fname, 'rb'))).digest()) for fname in fnamelst]
Se você quiser apenas 128 bits de resumo, você pode fazer .digest()[:16]
.
Isso fornecerá uma lista de tuplas, cada uma contendo o nome de seu arquivo e seu hash.
Novamente, questiono fortemente o uso do MD5. Você deve pelo menos usar o SHA1 e, dadas as falhas recentes descobertas no SHA1 , provavelmente nem isso. Algumas pessoas pensam que, desde que você não esteja usando o MD5 para fins 'criptográficos', você estará bem. Mas as coisas tendem a acabar tendo um escopo mais amplo do que o esperado inicialmente, e sua análise de vulnerabilidade casual pode ser completamente falha. É melhor simplesmente adquirir o hábito de usar o algoritmo certo imediatamente. É só digitar um monte diferente de letras. Não é tão difícil.
Aqui está uma maneira mais complexa, mas eficiente em termos de memória :
import hashlib
def hash_bytestr_iter(bytesiter, hasher, ashexstr=False):
for block in bytesiter:
hasher.update(block)
return hasher.hexdigest() if ashexstr else hasher.digest()
def file_as_blockiter(afile, blocksize=65536):
with afile:
block = afile.read(blocksize)
while len(block) > 0:
yield block
block = afile.read(blocksize)
[(fname, hash_bytestr_iter(file_as_blockiter(open(fname, 'rb')), hashlib.md5()))
for fname in fnamelst]
E, novamente, como o MD5 está quebrado e realmente não deve mais ser usado:
[(fname, hash_bytestr_iter(file_as_blockiter(open(fname, 'rb')), hashlib.sha256()))
for fname in fnamelst]
Mais uma vez, você pode fazer [:16]
a chamada depois hash_bytestr_iter(...)
se quiser apenas 128 bits digeridos.
md5sum
?