これに対する答えを探してみましたが、あなたのためにそれを行うソフトウェアしか見つけられないようです. Pythonでこれを行う方法を知っている人はいますか?
3 に答える
ダウンロードしたファイルのハッシュを.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()
トレントファイルからハッシュ値を抽出した方法は次のとおりです。
#!/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}'
それが役に立てば幸い :)
これによると、次のようなデータの部分を検索することで、ファイルのmd5sumsを見つけることができるはずです。
d[...]6:md5sum32:[hash is here][...]e
(SHAは仕様の一部ではありません)