У меня есть обзор для ответа на этот вопрос, но я только могу найти программное обеспечение, которое сделает это за вас. Кто-нибудь знает, как это сделать в python?Извлеките хэш SHA1 из торрент-файла
ответ
я написал кусок кода 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()
Не знаю, решила ли эта проблема ОП, но она определенно решила мою проблему (как только я преодолел нарушенность пакета bencode: http://stackoverflow.com/questions/2693963/importing-bittorrent-bencode-module). Благодаря! –
Я всегда хотел иметь такой инструмент и собирался вникать в старый официальный клиент python, чтобы узнать, как его написать. Благодаря!! – netvope
Согласно this, вы должны быть в состоянии найти md5sums файлов с помощью функции поиска для части данных, которая выглядит как:
d[...]6:md5sum32:[hash is here][...]e
(SHA не входит в спецификацию)
Просто найдите SHA на странице, с которой вы связались, и увидите, что она широко используется. Также цитируйте: 'md5sum: (необязательно) 32-символьный hex [...] Это вообще не используется BitTorrent, но оно включено в некоторые программы. –
А я вижу, что-то вроде' d [... ] 9: info_hash [длина]: [SHA hash] e' –
Я боюсь, что нет. Как я уже упоминал в вопросительных комментариях, для самих файлов нет хеша SHA1, но для каждого небольшого фрагмента файла. Хэш-элементы полезны, потому что их можно проверить в начале процесса загрузки. Как только у вас будет одна действительная часть, вы можете поделиться ею с другими сверстниками ... Это говорит о том, что ваше решение md5 имеет то преимущество, что оно простое. Он просто не гарантированно доступен во всех файлах .torrent. –
Здесь как I'v е извлеченное значение 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, так как это именно то, что я хотел сделать, когда я посетил вопрос о «извлечении хэша SHA1 из файла torrent». – sjy
Хорошая небольшая часть кода, bencode не находится в Debian/Ubuntu dist, поэтому вам нужно _pip install_ it, или мне проще использовать модуль 'bzrlib.bencode' от _python-bzrlib_. – marcz
торрент файл хранит SHA1, каждые * штуки * общих файлов и SHA1 метаданных torrent * (метафонический хеш) *. Какой хэш вы хотите точно? –
Это будет хэш для каждой части. Не содержит ли файл хеш для завершенного файла для проверки ошибок? – 2010-04-03 20:31:41
Некоторые .torrent-файлы содержат хеш-файл md5 для каждого файла, но это дополнительное расширение для формата файла. Хэш хэшей может использоваться для проверки правильности файлов. Вы просто проверяете, есть ли все части, и все ли они имеют правильный хеш. –