【问题标题】:Extract the SHA1 hash from a torrent file从 torrent 文件中提取 SHA1 哈希
【发布时间】:2011-02-04 01:51:05
【问题描述】:

我已经四处寻找这个问题的答案,但我似乎只能找到可以为您解决问题的软件。有人知道如何在 python 中执行此操作吗?

【问题讨论】:

  • 一个 torrent 文件存储了每个 pieces 共享文件的 SHA1 和 torrent 元数据 (元信息哈希) 的 SHA1。你到底想要哪个哈希?
  • 这将是每个部分的哈希值。该文件是否还包含已完成文件的哈希以检查错误?
  • 一些 .torrent 文件包含每个文件的 md5 哈希值,但这是文件格式的可选扩展名。碎片散列当然可以用来检查文件的有效性。您只需检查所有部分是否都存在以及它们是否都具有正确的哈希值。

标签: python hash extract sha1 bittorrent


【解决方案1】:

我编写了一段 Python 代码,用于根据 .torrent 文件中的内容验证下载文件的哈希值。假设您想检查下载是否损坏,您可能会发现这很有用。

您需要bencode package 才能使用它。 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 spec 以更详细地了解这一点。

完整代码如下:

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()

【讨论】:

  • 不知道这是否解决了 OP 的问题,但它确实解决了我的问题(一旦我通过了 bencode 包的损坏:stackoverflow.com/questions/2693963/…)。谢谢!
  • 我一直想有这样一个工具,正准备去挖掘旧的官方python客户端,想知道怎么写。谢谢!!
【解决方案2】:

我是如何从 torrent 文件中提取 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}'

希望,它会有所帮助:)

【讨论】:

  • 给你的是种子的信息哈希
  • +1 因为这正是我在访问有关“从 torrent 文件中提取 SHA1 哈希”的问题时想要做的。
  • 不错的一小段代码,bencode 不在 Debian/Ubuntu dist 中,所以你必须 pip install 它,或者我发现使用 bzrlib.bencode 模块更容易python-bzrlib.
【解决方案3】:

根据this,您应该可以通过搜索看起来像的部分数据找到文件的md5sum:

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

(SHA 不是规范的一部分)

【讨论】:

  • 只需在您链接的页面上搜索 SHA,您就会看到它被广泛使用。另引用:md5sum: (optional) a 32-character hex[...] This is not used by BitTorrent at all, but it is included by some programs
  • 啊,我明白了,就像d[...]9:info_hash[length]:[SHA hash]e
  • 恐怕不行。正如我在问题 cmets 中提到的,文件本身没有 SHA1 哈希,但对于每个小文件片段。碎片散列很有用,因为它们可以在下载过程的早期进行验证。只要您有一个有效的部分,您就可以与其他同行分享它......也就是说,您的 md5 解决方案具有简单的优势。只是不保证在所有 .torrent 文件中都可用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-26
相关资源
最近更新 更多