从 torrent 文件中提取 SHA1 哈希值

发布于 2024-08-27 23:45:13 字数 65 浏览 10 评论 0原文

我已经四处寻找这个问题的答案,但我似乎只能找到可以为您做到这一点的软件。有谁知道如何在 python 中做到这一点?

I've had a look around for the answer to this, but I only seem to be able to find software that does it for you. Does anybody know how to go about doing this in python?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

平定天下 2024-09-03 23:45:14

我编写了一段 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 字节哈希值(每个块一个)。然后将这些哈希值与磁盘上文件片段的哈希值进行比较。

此代码中唯一复杂的部分是处理多文件 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()

I wrote a piece of python code that verifies the hashes of downloaded files against what's in a .torrent file. Assuming you want to check a download for corruption you may find this useful.

You need the bencode package to use this. Bencode is the serialization format used in .torrent files. It can marshal lists, dictionaries, strings and numbers somewhat like JSON.

The code takes the hashes contained in the info['pieces'] string:

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

That string contains a succession of 20 byte hashes (one for each piece). These hashes are then compared with the hash of the pieces of on-disk file(s).

The only complicated part of this code is handling multi-file torrents because a single torrent piece can span more than one file (internally BitTorrent treats multi-file downloads as a single contiguous file). I'm using the generator function pieces_generator() to abstract that away.

You may want to read the BitTorrent spec to understand this in more details.

Full code bellow:

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()
故事↓在人 2024-09-03 23:45:14

下面是我如何从 torrent 文件中提取哈希值:

#!/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}'

希望,它有帮助:)

Here how I've extracted HASH value from torrent file:

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

It is the same as running command:

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

Hope, it helps :)

奈何桥上唱咆哮 2024-09-03 23:45:14

如果有人想知道如何从 BitTorrent v2 兼容 torrent 中提取文件哈希值,您可以使用此命令行工具

In case if anybody wonders how to extract file hashes from BitTorrent v2 compatible torrents, you can use this command line tool.

作业与我同在 2024-09-03 23:45:14

根据 this,您应该能够通过搜索以下部分找到文件的 md5sums:数据如下:

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

(SHA 不是规范的一部分)

According to this, you should be able to find the md5sums of files by searching for the part of the data that looks like:

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

(SHA is not part of the spec)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文