Extrae el hash SHA1 de un archivo torrent

He echado un vistazo alrededor de la respuesta a esto, pero parece que solo puedo encontrar un software que lo haga por usted. ¿Alguien sabe cómo hacer esto en Python?

Escribí un fragmento de código de Python que verifica los hashes de los archivos descargados contra lo que hay en un archivo .torrent . Suponiendo que desea comprobar una descarga en busca de daños, puede que le resulte útil.

Necesitas el paquete bencode para usar esto. Bencode es el formato de serialización usado en archivos .torrent. Puede reunir listas, diccionarios, cadenas y números de alguna manera como JSON.

El código toma los hashes contenidos en la cadena de info['pieces'] :

 torrent_file = open(sys.argv[1], "rb") metainfo = bencode.bdecode(torrent_file.read()) info = metainfo['info'] pieces = StringIO.StringIO(info['pieces']) 

Esa cadena contiene una sucesión de hashes de 20 bytes (uno para cada pieza). Estos hashes se comparan con el hash de las piezas de los archivos en disco.

La única parte complicada de este código es manejar torrents de múltiples archivos porque una sola pieza de torrent puede abarcar más de un archivo (internamente BitTorrent trata las descargas de múltiples archivos como un solo archivo contiguo) . Estoy usando la función generadora pieces_generator() para abstraer eso.

Es posible que desee leer la especificación de BitTorrent para comprender esto con más detalles.

Código completo abajo:

 import sys, os, hashlib, StringIO, bencode def pieces_generator(info): """Yield pieces from download file(s).""" piece_length = info['piece length'] if 'files' in info: # yield pieces from a multi-file torrent piece = "" for file_info in info['files']: path = os.sep.join([info['name']] + file_info['path']) print path sfile = open(path.decode('UTF-8'), "rb") while True: piece += sfile.read(piece_length-len(piece)) if len(piece) != piece_length: sfile.close() break yield piece piece = "" if piece != "": yield piece else: # yield pieces from a single file torrent path = info['name'] print path sfile = open(path.decode('UTF-8'), "rb") while True: piece = sfile.read(piece_length) if not piece: sfile.close() return yield piece def corruption_failure(): """Display error message and exit""" print("download corrupted") exit(1) def main(): # Open torrent file torrent_file = open(sys.argv[1], "rb") metainfo = bencode.bdecode(torrent_file.read()) info = metainfo['info'] pieces = StringIO.StringIO(info['pieces']) # Iterate through pieces for piece in pieces_generator(info): # Compare piece hash with expected hash piece_hash = hashlib.sha1(piece).digest() if (piece_hash != pieces.read(20)): corruption_failure() # ensure we've read all pieces if pieces.read(): corruption_failure() if __name__ == "__main__": main() 

Aquí cómo he extraído el valor HASH de un archivo torrent:

 #!/usr/bin/python import sys, os, hashlib, StringIO import bencode def main(): # Open torrent file torrent_file = open(sys.argv[1], "rb") metainfo = bencode.bdecode(torrent_file.read()) info = metainfo['info'] print hashlib.sha1(bencode.bencode(info)).hexdigest() if __name__ == "__main__": main() 

Es lo mismo que ejecutar el comando:

 transmissioncli -i test.torrent 2>/dev/null | grep "^hash:" | awk '{print $2}' 

Espero eso ayude 🙂

De acuerdo con esto , deberías poder encontrar los md5sums de archivos buscando la parte de los datos que se ve así:

d[...]6:md5sum32:[hash is here][...]e

(SHA no es parte de la especificación)