25

これに対する答えを探してみましたが、あなたのためにそれを行うソフトウェアしか見つけられないようです. Pythonでこれを行う方法を知っている人はいますか?

4

3 に答える 3

33

ダウンロードしたファイルのハッシュを.torrent ファイルの内容と照合する Python コードを作成しました。ダウンロードの破損をチェックしたい場合、これが役立つ場合があります。

これを使用するにはbencode パッケージが必要です。Bencode は、.torrent ファイルで使用されるシリアル化形式です。リスト、辞書、文字列、数値を JSON のようにマーシャリングできます。

info['pieces']このコードは、文字列に含まれるハッシュを取得します。

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

その文字列には、連続する 20 バイトのハッシュ (各ピースに 1 つ) が含まれています。これらのハッシュは、ディスク上のファイルの断片のハッシュと比較されます。

このコードの唯一の複雑な部分は、単一の torrentピースが複数のファイルにまたがることができるため、複数ファイルの torrent を処理することです(内部的に、BitTorrent は複数ファイルのダウンロードを単一の連続したファイルとして扱います)。ジェネレーター関数pieces_generator()を使用してそれを抽象化しています。

これをより詳細に理解するには、 BitTorrent の仕様を読むことをお勧めします。

以下の完全なコード:

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()
于 2010-04-04T05:59:06.980 に答える
17

トレントファイルからハッシュ値を抽出した方法は次のとおりです。

#!/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()

コマンドを実行するのと同じです:

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

それが役に立てば幸い :)

于 2010-11-13T16:07:30.487 に答える
-2

これによると、次のようなデータの部分を検索することで、ファイルのmd5sumsを見つけることができるはずです。

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

(SHAは仕様の一部ではありません)

于 2010-04-04T07:11:41.470 に答える