我已经到处寻找答案,但是似乎只能找到可以满足您需求的软件。有人知道如何在python中执行此操作吗?
我写了一段python代码,根据 .torrent文件 中的内容验证 下载文件 的哈希值。假设您要检查下载是否损坏,则可能会发现此功能有用。 __
您需要bencode包才能使用它。Bencode是.torrent文件中使用的序列化格式。它可以封送列表,字典,字符串和数字,就像JSON。
该代码采用info['pieces']字符串中包含的哈希值:
info['pieces']
torrent_file = open(sys.argv[1], "rb") metainfo = bencode.bdecode(torrent_file.read()) info = metainfo['info'] pieces = StringIO.StringIO(info['pieces'])
该字符串包含连续的20个字节的哈希值(每段一个)。然后,将这些哈希与磁盘文件碎片的哈希进行比较。
此代码的唯一复杂部分被处理多文件种子因为单个洪流 片 可以跨越多于一个文件 (内部BitTorrent的治疗多文件下载作为单个连续文件) 。我正在使用生成器函数pieces_generator()将其抽象化。
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()