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?

È stato utile?

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)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top