2

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

我一直在看这个例子:How to calculate the hash of a torrent using Java and am trying to convert it to 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.
}

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

d6:lengthi2847431620e4:name8:filename12:piece lengthi1143252e6:pieces50264

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

所以我的问题实际上归结为:应该散列的信息是后面的所有内容,4:info我应该在哪里停止收集散列数据?

4

2 回答 2

4

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

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

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

杂项。笔记:

假设 info 密钥是文件中的最后一件事(同样,它可能不是),那么在算法中“遗漏”的 SHA1 的单个字节是整个 torrent 的最终“e”(这只是一个单个 bencode 字典——所有 torrent 文件都以“d”开头并以“e”结尾)。

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

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

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

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

我假设您有代码来执行实际的 SHA1。你在哪个平台上工作?

于 2013-09-25T15:19:39.430 回答
0

.torrent 规范是免费提供的,应该可以帮助您很容易地理解文件格式。您需要做的就是对info密钥的内容进行 SHA1 以获取信息哈希。

于 2012-12-02T16:36:00.477 回答