2013-11-03 6 views
4

Я использую C++ для анализа информации хэш торрента, и у меня возникли проблемы с получением «правильный» хэш-значение по сравнению с этого сайта:Расчет инфо-хэш торрента файла

http://i-tools.org/torrent

Я построил очень простой пример игрушек, чтобы убедиться, что у меня есть основы.

Я открыл .torrent файл в возвышенном и снял все для информационного словаря за исключением, поэтому у меня есть файл, который выглядит следующим образом:

d6:lengthi729067520e4:name31:ubuntu-12.04.1-desktop-i386.iso12:piece lengthi524288e6:pieces27820:¡´E¶ˆØËš3í ..............(more unreadable stuff.....).......... 

Я прочитал этот файл и разобрать его с этим кодом :

#include <string> 
#include <sstream> 
#include <iomanip> 
#include <fstream> 
#include <iostream> 

#include <openssl/sha.h> 


void printHexRep(const unsigned char * test_sha) { 

    std::cout << "CALLED HEX REP...PREPPING TO PRINT!\n"; 
    std::ostringstream os; 
    os.fill('0'); 
    os << std::hex; 
    for (const unsigned char * ptr = test_sha; ptr < test_sha + 20; ptr++) { 

     os << std::setw(2) << (unsigned int) *ptr; 
    } 
    std::cout << os.str() << std::endl << std::endl; 
} 


int main() { 

    using namespace std; 

    ifstream myFile ("INFO_HASH__ubuntu-12.04.1-desktop-i386.torrent", ifstream::binary); 

    //Get file length 
    myFile.seekg(0, myFile.end); 
    int fileLength = myFile.tellg(); 
    myFile.seekg(0, myFile.beg); 

    char buffer[fileLength]; 

    myFile.read(buffer, fileLength); 
    cout << "File length == " << fileLength << endl; 
    cout << buffer << endl << endl; 

    unsigned char datSha[20]; 
    SHA1((unsigned char *) buffer, fileLength, datSha); 
    printHexRep(datSha); 

    myFile.close(); 

    return 0; 
} 

Собирать так:

g++ -o hashes info_hasher.cpp -lssl -lcrypto 

И я встретился с этим outpu т:

4d0ca7e1599fbb658d886bddf3436e6543f58a8b 

Когда я ожидал этот вывод:

14FFE5DD23188FD5CB53A1D47F1289DB70ABF31E 

Кто-нибудь знает, что я могу делать неправильно здесь? Может ли проблема заключаться в нечитаемости конца файла? Нужно ли сначала разбирать это как шестую или что-то еще?

ответ

8

Убедитесь, что в конце файла нет новой строки, вы также можете убедиться, что она заканчивается символом 'e'.

Информация-хэш торрент-файла - это хэш SHA-1 информационного раздела (в кодировке) из файла .torrent. По сути вам нужно декодировать файл (он закодирован) и запомнить смещения байта, где начинается и заканчивается содержимое значения, связанного с ключом «info». Это диапазон байтов, который вам нужен для хэша.

Например, если это торрент-файл:

d4:infod6:pieces20:....................4:name4:test12:piece lengthi1024ee8:announce27:http://tracker.com/announcee 

Вы тусклый только хэш этот раздел:

d6:pieces20:....................4:name4:test12:piece lengthi1024ee 

Для получения дополнительной информации о bencoding см BEP3.

+0

Я уверен, что проблема была с символами новой строки! Благодаря! Пример, приведенный выше, представляет собой игрушечный пример, я удалил все в торрент-файле, за исключением инфо-словаря. – Ethan

+2

Будьте уверены, что пример торрент-файла, предоставленный Arvid, как корневой словарь, так и инфо-словарь не отсортирован. В соответствии со спецификацией bencode словарь должен быть отсортирован. Однако согласованная конвенция, когда информационный словарь по какой-либо причине является несортированным, заключается в хешировании информационного словаря, как он есть (несортированный), как объясняется выше Arvid. – Encombe

+3

да, хорошо пункт. Это также может служить иллюстрацией того, что даже когда неправильно закодированный словарный словарь некорректно сортируется, информация-хэш по-прежнему является хешем дословной формы. Некоторые клиенты (используемые) декодируют и перекодируют до хэширования, что приводит к неправильным информационным хэшам в таких случаях. – Arvid

1

Расчет SHA1 так же прост, как то, что вы написали, более или менее. Вероятно, ошибка связана с данными, которые вы ее подаете, если вы получаете неправильный ответ от функции библиотеки.

Я не могу говорить с работами по подготовке файлов торрентов, но я вижу несколько проблем. Если вы перейдете в SHA1 docs, обратите внимание, что функция SHA1 никогда не требует собственной длины дайджеста в качестве параметра. Затем вы должны быть уверены, что техника, которую вы используете для чтения содержимого файла, точно всасывает точные байты, а не перевод.

Менее критическое предложение стиля: используйте третий параметр для SHA1. Общее правило, статическое хранилище в библиотеке лучше избегать. Всегда предпочитайте поставлять свой собственный буфер. Кроме того, там, где у вас есть жестко закодированная 20 в вашей функции печати, это замечательное место для этой константы, длина которой вы флиртуете.

+0

whooopss совершенно неправильно читал и думал, что длина, переданная SHA1, была для принимающего массива! Я исправил это, и, очевидно, я получаю другой хеш, но он по-прежнему не является правильным. Я думаю, что проблема связана с файлом torrent-файла, который я или не делаю. Торрент-файл, который я обрезал фронт, - это тот же самый, который я подаю на эту веб-страницу, чтобы получить другой результат, поэтому он в корне не поврежден или что-то еще. Я изменил опубликованный код, чтобы отразить изменения. – Ethan