我已经查看了相关的答案,但似乎只有能够自动完成此任务的软件。请问是否有人知道如何在Python中实现此功能?
我已经查看了相关的答案,但似乎只有能够自动完成此任务的软件。请问是否有人知道如何在Python中实现此功能?
我写了一段Python代码,用于验证已下载的文件的哈希值与.torrent文件中的哈希值是否匹配。如果你想检查下载文件是否损坏,你可能会发现这个代码很有用。
你需要使用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字节的哈希值(每个块一个)。然后,这些哈希值会与磁盘文件中每个块的哈希值进行比较。
这段代码中唯一复杂的部分是处理多文件种子,因为单个种子“块”可以跨越多个文件 (内部 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()
python2
,因此您需要安装python-pip
而不是默认的python3-pip
才能使其正常工作,还需运行pip2 install bencode
。要启动脚本,请运行python2 yourscript.py file.torrent
。如果没有问题,则只会输出被测试文件的名称,否则将输出错误信息。 - Smeterlink我是如何从种子文件中提取HASH值的:
#!/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}'
希望它能有所帮助 :)
bzrlib.bencode
模块。 - marczd[...]9:info_hash[length]:[SHA hash]e
这样的东西。 - Brendan Long