Расчет хеша торрент-файла

Я использую 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

И я встретился с этим выводом:

4d0ca7e1599fbb658d886bddf3436e6543f58a8b

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

14FFE5DD23188FD5CB53A1D47F1289DB70ABF31E

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

2 ответа

Решение

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

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

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

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

Вы хотите просто хешировать этот раздел:

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

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

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

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

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

Другие вопросы по тегам