python - Extraiga el hash SHA1 de un archivo torrent
extract bittorrent (3)
Aquí cómo he extraído el valor HASH del 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 :)
He echado un vistazo para encontrar la respuesta, pero parece que solo puedo encontrar un software que lo haga por ti. ¿Alguien sabe cómo hacer esto en Python?
De acuerdo con this , debería 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)
Escribí un fragmento de código python que verifica los hashes de los archivos descargados con lo que está en un archivo .torrent . Suponiendo que desea verificar una descarga por corrupción, puede resultar útil.
Necesitas el paquete de bencode para usar esto. Bencode es el formato de serialización utilizado en los archivos .torrent. Puede ordenar listas, diccionarios, cadenas y números como JSON.
El código toma los valores 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 archivo (s) en disco.
La única parte complicada de este código es manejar torrents de archivos múltiples porque una sola pieza de torrent puede abarcar más de un archivo (internamente BitTorrent trata las descargas de archivos múltiples como un solo archivo contiguo) . Estoy usando la función del generador pieces_generator()
para abstraer eso.
Es posible que desee leer la especificación de BitTorrent para entender esto en más detalles.
Código completo a continuación:
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()