Извлечь хеш SHA1 из торрент-файла

Я поискал ответ на этот вопрос, но, кажется, могу найти только программное обеспечение, которое сделает это за вас. Кто-нибудь знает, как это сделать на Python?


person Community    schedule 03.04.2010    source источник
comment
В торрент-файле хранится SHA1 каждого фрагмента общих файлов и SHA1 метаданных торрента (хэш метаинфо). Какой именно хеш вы хотите?   -  person Alex Jasmin    schedule 04.04.2010
comment
Это будет хеш для каждой из частей. Не содержит ли файл также хеш завершенного файла для проверки на наличие ошибок?   -  person    schedule 04.04.2010
comment
Некоторые файлы .torrent включают хэш md5 каждого файла, но это необязательное расширение формата файла. Хеш-код частей, конечно же, можно использовать для проверки достоверности файлов. Вы просто проверяете, все ли на месте и все ли у них правильный хеш.   -  person Alex Jasmin    schedule 04.04.2010


Ответы (3)


Я написал фрагмент кода на 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()
person Alex Jasmin    schedule 04.04.2010
comment
Не знаю, решило ли это проблему OP, но это определенно решило мою (как только я преодолел поломку пакета bencode: stackoverflow.com/questions/2693963/). Спасибо! - person Nicholas Knight; 25.04.2010
comment
Я всегда хотел иметь такой инструмент и собирался покопаться в старом официальном клиенте Python, чтобы узнать, как его написать. Спасибо!! - person netvope; 28.05.2010

Вот как я извлек значение 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}'

Надеюсь, поможет :)

person grundic    schedule 13.11.2010
comment
Это дает вам хэш информации торрента. - person Alex Jasmin; 16.11.2010
comment
+1 так как именно это я и хотел сделать, когда задал вопрос об извлечении хэша SHA1 из торрент-файла. - person sjy; 19.06.2014
comment
Хороший небольшой фрагмент кода, bencode отсутствует в дистрибутиве Debian / Ubuntu, поэтому вам нужно установить pip, или мне проще использовать модуль bzrlib.bencode из python-bzrlib . - person marcz; 02.03.2017

Согласно this, вы сможете найти md5-суммы файлов, выполнив поиск по части данные, которые выглядят так:

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

(SHA не является частью спецификации)

person Brendan Long    schedule 04.04.2010
comment
Просто найдите SHA на странице, на которую вы указали ссылку, и вы увидите, что он широко используется. Также процитирую: md5sum: (optional) a 32-character hex[...] This is not used by BitTorrent at all, but it is included by some programs - person Alex Jasmin; 04.04.2010
comment
Ах, понятно, так что-то вроде d[...]9:info_hash[length]:[SHA hash]e - person Brendan Long; 04.04.2010
comment
Я не боюсь. Как я уже упоминал в комментариях к вопросу, нет хэша SHA1 для самих файлов, а для каждого небольшого фрагмента файла. Хеш-код Pieces полезен, потому что его можно проверить на раннем этапе процесса загрузки. Как только у вас есть один действительный элемент, вы можете поделиться им с другими коллегами ... Тем не менее, ваше решение md5 имеет то преимущество, что оно простое. Его доступность во всех торрент-файлах не гарантируется. - person Alex Jasmin; 04.04.2010