从torrent文件中提取SHA1哈希 [英] Extract the SHA1 hash from a torrent file

查看:470
本文介绍了从torrent文件中提取SHA1哈希的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经找到了解决方案的答案,但我似乎只能找到适合您的软件。有人知道如何去做这样的Python吗?

解决方案

我写了一段python代码,验证下载的文件 .torrent文件中的内容进行比较。假设你想检查下载的腐败,你可能会发现这是有用的。



你需要 bencode包来使用它。 Bencode是.torrent文件中使用的序列化格式。它可以列表,字典,字符串和数字像JSON一样。


$ b 代码将包含在 info ['pieces']中的哈希 string:

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

该字符串包含20个字节的散列(每个散列一个)。然后将这些散列与磁盘上的文件散列进行比较。



这段代码中唯一复杂的部分是处理多文件文件,因为单个torrent文件片段可以跨越多个文件(内部BitTorrent将多文件下载视为单个连续文件)。我使用了生成器函数 pieces_generator()来将它抽象出来。



您可能想阅读<一个href =http://wiki.theory.org/BitTorrentSpecification =noreferrer> BitTorrent规范了解更多细节。



完整代码下面:
$ b

  import sys,os,hashlib,StringIO,bencode 

def pieces_generator(info):
从下载文件中得到的部分。
piece_length = info ['piece length']
如果'files'in info:#从一个多文件torrent中产生多块文件
piece =
for info ['files']中的file_info:
path = os.sep.join([info ['name ']] + file_info ['path'])
打印路径
sfile = open(path.decode('UTF-8'),rb)
,True:
piece + = sfile.read(piece_length-len(piece))
len(piece)!= piece_length:
sfile.close()
break
yield piece
piece =
if piece!=:
yield piece
else:#yield pieces从一个文件洪流
path = info ['name']
打印路径
sfile = open(path.decode('UTF-8'),rb)
而真:
piece = sfile.read(piece_length)
如果不是piece:
sfile.close()
return
yield piece

$ def corruption_failure():
显示错误信息并退出
print(下载已损坏)
exit(1)

def main ():
#打开torrent文件
torrent_file = open(sys.argv [1],rb)
metainfo = bencode.bdecode(torrent_file.read())
info = metainfo ['info']
pieces = StringIO.StringIO(info ['pieces'])
#遍历片段
如果(piece_hash!= pieces.read(20)):$:
# b $ b corruption_failure()
#确保我们读过所有的块
如果pieces.read():
corruption_failure()

if __name__ ==__main__ :
main()


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?

解决方案

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

这篇关于从torrent文件中提取SHA1哈希的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆