Estrarre l'hash SHA1 da un file torrent
-
24-09-2019 - |
Domanda
Ho avuto un'occhiata in giro per la risposta a questo, ma mi sembra solo di essere in grado di trovare il software che fa per voi. Qualcuno sa come andare a fare questo in Python?
Soluzione
ho scritto un pezzo di codice python che consente di verificare gli hash di file scaricabili contro quello che c'è in un file .torrent . Supponendo che si desidera controllare un download per la corruzione si può trovare questo utile.
È necessario il bencode pacchetto per utilizzare questo. Bencode è il formato di serializzazione utilizzato in file .torrent. Può schierare liste, dizionari, stringhe e numeri un po 'come JSON.
Il codice prende gli hash contenute nella stringa info['pieces']
:
torrent_file = open(sys.argv[1], "rb")
metainfo = bencode.bdecode(torrent_file.read())
info = metainfo['info']
pieces = StringIO.StringIO(info['pieces'])
Tale stringa contiene una successione di 20 byte hash (uno per ogni pezzo). Questi hash sono poi confrontati con l'hash dei pezzi di file (s) su disco.
L'unica parte complicata di questo codice è la gestione torrents multi-file perché un unico torrente pezzo può includere più di un file (tratta internamente BitTorrent download multi-file come un unico file contigui ) . Sto utilizzando la funzione di generatore di pieces_generator()
a astratto che via.
Si consiglia di leggere il BitTorrent spec per capire questo più in dettaglio.
Codice muggito completa:
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()
Altri suggerimenti
Ecco come ho estratto valore hash dal file 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()
E 'lo stesso di comando in esecuzione:
transmissioncli -i test.torrent 2>/dev/null | grep "^hash:" | awk '{print $2}'
La speranza, aiuta:)
questo , si dovrebbe essere in grado di trovare i md5sums di file attraverso la ricerca di la parte dei dati che assomiglia a:
d[...]6:md5sum32:[hash is here][...]e
(SHA, non fa parte delle specifiche)