4

我正在使用 C++ 解析 torrent 文件的信息哈希,与此站点相比,我无法获得“正确”的哈希值:

http://i-tools.org/torrent

我构建了一个非常简单的玩具示例,以确保我掌握了正确的基础知识。

我在 sublime 中打开了一个 .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

有人知道我在这里可能做错了什么吗?问题可能出在文件末尾的不可读性上吗?我需要先将其解析为十六进制还是什么?

4

2 回答 2

9

确保文件末尾没有换行符,您可能还想确保它以“e”结尾。

torrent 文件的 info-hash 是 .torrent 文件中 info-section(以编码形式)的 SHA-1 哈希。本质上,您需要解码文件(它已被编码)并记住与“info”键关联的值的内容开始和结束的字节偏移量。这是您需要散列的字节范围。

例如,如果这是 torrent 文件:

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

你想对这个部分进行散列:

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

有关编码的更多信息,请参阅BEP3

于 2013-11-05T22:13:17.287 回答
1

SHA1 计算和你写的一样简单,或多或少。如果您从库函数中得到错误的答案,错误可能在您提供的数据中。

我无法谈论您所做的 torrent 文件准备工作,但我确实看到了一些问题。如果您要重新访问SHA1 文档,请注意 SHA1 函数从不需要自己的摘要长度作为参数。接下来,您需要非常确定您用于读取文件内容的技术是忠实地吸收确切的字节,而不是翻译。

一个不太重要的风格建议:利用 SHA1 的第三个参数。一般规则,最好避免在库中进行静态存储。总是喜欢提供自己的缓冲区。此外,如果您在打印函数中有一个硬编码的 20,那么对于您一直在调情的摘要长度常数来说,这是一个了不起的地方。

于 2013-11-03T03:43:50.640 回答