创建 torrent 哈希信息

Ara*_*raw 2 c++ bittorrent info-hash

如何在 torrent 文件上生成 torrent 哈希信息。

我一直在看这个例子:如何使用 Java 计算 torrent 的哈希值,并尝试将其转换为 C++。这是我到目前为止的代码:

void At::ReadTorrent::TorrentParser::create_hash(std::string torrentstub)
{
    std::string info;
    int counter = 0;

    while(info.find("4:info") == -1)
    {
        info.push_back(torrentstub[counter]);
        counter++;
    }

    unsigned char array[torrentstub.size()];
    int test = 0;

    for(int data; (data = torrentstub[counter]) > -1;)
    {
         array[test++] = data;
         counter++;
    }
    std::cout << array << std::endl;

    //SHA-1 some value here to generate the hash.
}
Run Code Online (Sandbox Code Playgroud)

参数torrentstub是以字符串表示的 torrent 文件。据我了解,我必须获得之后的信息4:info。我认为这工作正常,例如:

d6:lengthi2847431620e4:name8:filename12:piece lengthi1143252e6:pieces50264
Run Code Online (Sandbox Code Playgroud)

之后只有我无法读取的信息,我猜这是一些二进制数据?

所以我的问题实际上可以归结为:应该对 后面的所有内容进行哈希处理的信息4:info,以及我应该在哪里停止收集哈希数据?

Not*_*ted 5

您基于此的示例代码似乎假设信息密钥是 torrent 文件中的最后一件事(可能不是,因此请阅读整个答案以了解整个故事)。因此,它将覆盖从“:info”后面的字节开始的文件的其余部分(减去 1 个字节)。您会看到类似“...:infod6:length...”的内容。SHA1 以“d6:length...”开头,到文件末尾减去 1 个字节(不包括最后一个字节,通常是“e”)。

例如,如果 torrent 文件大小为 43125 字节,并且“:info”从偏移量 362 开始,则 SHA 数据从偏移量 367 开始,一直到偏移量 43123(即 42757 字节)。

您可能知道您的 torrent 文件确实以 info 键结尾。如果你不知道,那么你的算法一定更复杂一些。一个 torrent 文件是 bencode 的,信息密钥由一个 bencode“字典”组成(在维基百科中搜索 bencode 并阅读文章 - 它非常容易理解)。“:info”后面的“d”启动以“e”结尾的字典。字典的长度没有编码,因此知道它结束位置的唯一方法是解析内容,直到找到结束它的“e”。如果文件格式正确,则字典的内容将由一系列格式良好的编码元素(以及进一步嵌套的元素)组成。最终您会发现一个元素(而不是另一个元素)末尾后面有一个“e”。这个“e”结束了字典。SHA1 覆盖了本字典的全部内容,包括开头的“d”和结尾的“e”。其他编码元素也可以遵循这一点。这些不包含在 SHA1 计算中。

杂项。笔记:

假设信息密钥是文件中的最后一个内容(同样,也可能不是),算法中 SHA1“遗漏”的单个字节是整个 torrent 的最后一个“e”(这只是一个单个 Bencode 字典 - 所有 torrent 文件都以“d”开头并以“e”结尾)。

这是二进制数据,因此在填充 torrentstub[] 时必须按二进制数据读取。

您无法像示例中那样测试 -1 来确定何时结束。它所基于的代码在测试 -1 (eof) 时查看读取操作的结果,而不是数据本身。您必须使用 torrent 文件的长度减去数据的开头(“:info”之后)再减去 1 才能获得正确的长度。

您引用的示例代码实际上确实读取了最后一个字节,但在生成 SHA1 时将其排除。

读取一个字节,复制到字符串,然后重复重新扫描字符串,效率非常低。您已经将数据存储在数组中,因此只需使用 strstr (因为开头是 ASCII 数据)或自己扫描它(编码并不难,因为它是一个非常短的固定长度字符串)。

我假设您有执行实际 SHA1 的代码。您在什么平台上工作?