python python-3.x hashlib

Uso de hashlib para calcular el resumen md5 de un archivo en Python 3



python-3.x (3)

Creo que querías que el bucle for hiciera llamadas sucesivas a f.read(128) . Eso se puede hacer usando iter () y functools.partial () :

import hashlib from functools import partial def md5sum(filename): with open(filename, mode=''rb'') as f: d = hashlib.md5() for buf in iter(partial(f.read, 128), b''''): d.update(buf) return d.hexdigest() print(md5sum(''utils.py''))

Con Python 2.7, el siguiente código calcula el hexdigest mD5 del contenido de un archivo.

(EDIT: bueno, no realmente como las respuestas han mostrado, solo lo pensé).

import hashlib def md5sum(filename): f = open(filename, mode=''rb'') d = hashlib.md5() for buf in f.read(128): d.update(buf) return d.hexdigest()

Ahora, si ejecuto ese código usando python3, genera una excepción de error de tipo:

d.update(buf) TypeError: object supporting the buffer API required

Me di cuenta de que podía hacer que el código se ejecutara con python2 y python3 cambiándolo a:

def md5sum(filename): f = open(filename, mode=''r'') d = hashlib.md5() for buf in f.read(128): d.update(buf.encode()) return d.hexdigest()

Ahora todavía me pregunto por qué el código original dejó de funcionar. Parece que al abrir un archivo utilizando el modificador de modo binario, devuelve números enteros en lugar de cadenas codificadas como bytes (lo digo porque el tipo (buf) devuelve int). ¿Se explica este comportamiento en alguna parte?


Finalmente, cambié mi código a la versión de abajo (que me parece fácil de entender) después de hacer la pregunta. Pero probablemente lo cambie a la versión sugerida por Raymond Hetting unsing functools.partial.

import hashlib def chunks(filename, chunksize): f = open(filename, mode=''rb'') buf = "Let''s go" while len(buf): buf = f.read(chunksize) yield buf def md5sum(filename): d = hashlib.md5() for buf in chunks(filename, 128): d.update(buf) return d.hexdigest()


for buf in f.read(128): d.update(buf)

.. actualiza el hash secuencialmente con cada uno de los primeros valores de 128 bytes del archivo. Dado que la iteración sobre un bytes produce objetos int , se obtienen las siguientes llamadas que causan el error que encontró en Python3.

d.update(97) d.update(98) d.update(99) d.update(100)

que no es lo que quieres

En su lugar, desea:

def md5sum(filename): with open(filename, mode=''rb'') as f: d = hashlib.md5() while True: buf = f.read(4096) # 128 is smaller than the typical filesystem block if not buf: break d.update(buf) return d.hexdigest()