Извлеките хеш SHA1 из файла потока

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

22
задан Jon Seigel 3 May 2010 в 14:07
поделиться

2 ответа

Я написал фрагмент кода на Python, который проверяет хэши загруженных файлов по сравнению с тем, что находится в .torrent-файле . Предполагая, что вы хотите проверить загрузку на наличие повреждений, это может оказаться полезным.

Для использования вам понадобится пакет bencode . Bencode - это формат сериализации, используемый в файлах .torrent. Он может упорядочивать списки, словари, строки и числа наподобие JSON.

Код принимает хэши, содержащиеся в строке info ['piece'] :

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

Эта строка содержит последовательность из 20 байтовых хэшей (по одному для каждой части). Эти хэши затем сравниваются с хешами частей файла (ов) на диске.

Единственная сложная часть этого кода - обработка многофайловых торрентов, потому что один торрент кусок может охватывать более одного файла (внутри BitTorrent обрабатывает многофайловые загрузки как один непрерывный файл) . Я использую функцию генератора piece_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()
29
ответ дан 29 November 2019 в 04:33
поделиться

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

d [...] 6: md5sum32: [хеш здесь] [...] e

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

-2
ответ дан 29 November 2019 в 04:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: