Existe alguma maneira simples de gerar (e verificar) somas de verificação MD5 de uma lista de arquivos em Python? (Eu tenho um pequeno programa em que estou trabalhando e gostaria de confirmar as somas de verificação dos arquivos).
348
md5sum
?md5sum
. É por isso que programadores preocupados com segurança não devem usá-lo na minha opinião.md5sum
e a técnica descrita nesta questão SO deve ser evitado - é melhor usar SHA-2 ou SHA-3, se possível: en.wikipedia.org/wiki/Secure_Hash_AlgorithmsRespostas:
Você pode usar hashlib.md5 ()
Observe que, às vezes, você não poderá ajustar o arquivo inteiro na memória. Nesse caso, você terá que ler trechos de 4096 bytes sequencialmente e alimentá-los com o
md5
método:Nota:
hash_md5.hexdigest()
retornará a representação de sequência hexadecimal para o resumo, se você precisar apenas dos bytes compactadosreturn hash_md5.digest()
, para que não precise converter novamente.fonte
Existe uma maneira que é bastante ineficiente de memória .
único arquivo:
lista de arquivos:
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:
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 :
E, novamente, como o MD5 está quebrado e realmente não deve mais ser usado:
Mais uma vez, você pode fazer
[:16]
a chamada depoishash_bytestr_iter(...)
se quiser apenas 128 bits digeridos.fonte
Claramente, não estou adicionando nada fundamentalmente novo, mas adicionei esta resposta antes de comentar o status, além das regiões de código tornarem as coisas mais claras - de qualquer maneira, especificamente para responder à pergunta de @ Nemo da resposta de Omnifarious:
Por acaso, pensei um pouco sobre as somas de verificação (vim aqui procurando sugestões sobre tamanhos de bloco, especificamente) e descobri que esse método pode ser mais rápido do que você esperaria. Tomando o mais rápido (mas bastante típico)
timeit.timeit
ou/usr/bin/time
resultado de cada um dos vários métodos de checksum um arquivo de aprox. 11MB:Portanto, parece que o Python e / usr / bin / md5sum levam cerca de 30ms para um arquivo de 11MB. A
md5sum
função relevante (md5sum_read
na lista acima) é bastante semelhante à Omnifarious:É verdade que estas são de execuções únicas (
mmap
as que são sempre um pouco mais rápidas quando são feitas pelo menos algumas dúzias de execuções), e as minhas geralmente recebem um extraf.read(blocksize)
depois que o buffer é esgotado, mas é razoavelmente repetível e mostra quemd5sum
na linha de comando está não necessariamente mais rápido que uma implementação em Python ...EDIT: Desculpe pelo longo atraso, não olhei para isso há algum tempo, mas para responder à pergunta de @ EdRandall, vou escrever uma implementação do Adler32. No entanto, eu não corri os parâmetros para isso. É basicamente o mesmo que o CRC32 teria sido: em vez das chamadas init, update e digest, tudo é uma
zlib.adler32()
chamada:Observe que isso deve começar com a string vazia, pois as somas de Adler realmente diferem quando se inicia do zero em relação à sua soma para
""
, que é1
- o CRC pode começar com0
ele. OAND
-ing é necessário para torná-lo um número inteiro não assinado de 32 bits, o que garante que ele retorne o mesmo valor nas versões do Python.fonte
No Python 3.8 ou superior, você pode fazer
Considere usar em
hashlib.blake2b
vez demd5
(basta substituímd5
-loblake2b
no snippet acima). É criptograficamente seguro e mais rápido que o MD5.fonte
:=
operador é um "operador de atribuição" (novo no Python 3.8+); permite atribuir valores dentro de uma expressão maior; mais informações aqui: docs.python.org/3/whatsnew/3.8.html#assignment-expressionsfonte
Eu acho que confiar no invoke package e no md5sum binário é um pouco mais conveniente do que o subprocesso ou o pacote md5
Obviamente, isso pressupõe que você invocou e md5sum instalado.
fonte
path
for um caminho fornecido pelo usuário, isso permitirá que qualquer usuário execute comandos bash arbitrários no seu sistema.