计算torrent文件的info-hash

Eth*_*han 4 c++ hash bittorrent sha1 info-hash

我正在使用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.....)..........
Run Code Online (Sandbox Code Playgroud)

我读了这个文件并用这段代码解析它:

#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;
}
Run Code Online (Sandbox Code Playgroud)

像这样编译它:

g++ -o hashes info_hasher.cpp -lssl -lcrypto
Run Code Online (Sandbox Code Playgroud)

我遇到了这个输出:

4d0ca7e1599fbb658d886bddf3436e6543f58a8b
Run Code Online (Sandbox Code Playgroud)

当我期待这个输出:

14FFE5DD23188FD5CB53A1D47F1289DB70ABF31E
Run Code Online (Sandbox Code Playgroud)

有谁知道我在这里做错了什么?问题可能在于文件末尾的不可读性吗?我需要先将其解析为十六进制或其他内容吗?

Arv*_*vid 9

确保文件末尾没有换行符,您可能还需要确保以"e"结尾.

torrent文件的info-hash是来自.torrent文件的info-section(以bencoded形式)的SHA-1哈希.基本上你需要解码文件(它是bencoded)并记住字节偏移,其中与"info"键关联的值的内容开始和结束.这是您需要散列的字节范围.

例如,如果这是torrent文件:

d4:infod6:pieces20:....................4:name4:test12:piece lengthi1024ee8:announce27:http://tracker.com/announcee
Run Code Online (Sandbox Code Playgroud)

你想干这个部分:

d6:pieces20:....................4:name4:test12:piece lengthi1024ee
Run Code Online (Sandbox Code Playgroud)

有关bencoding的更多信息,请参阅BEP3.

  • 是的,好的一点.它也可以作为一个例子,即使在对已编码的字典进行错误排序时,信息散列仍然是逐字形式的散列.某些客户端(以前)在散列之前进行解码和重新编码,这会导致在这种情况下出现错误的信息哈希. (3认同)
  • 请注意Arvid给出的示例torrent文件,根词典和信息词典都是未排序的.根据bencode规范,必须对字典进行排序.然而,当信息字典由于某种原因未被排序时,约定的约定是将信息字典原样哈希(未分类),如上面的Arvid所解释的那样. (2认同)