创建torrent哈希信息

时间:2012-12-02 15:15:54

标签: c++ bittorrent info-hash

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

我一直在看这个例子:How to calculate the hash value of a torrent using Java我正在尝试将其转换为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之后的所有内容进行哈希处理,以及应该在何处停止收集哈希数据?

2 个答案:

答案 0 :(得分:4)

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

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

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

混杂。注意到:

假设信息键是文件中的最后一个(再次,它可能不是),算法中“遗漏”SHA1的单个字节是整个torrent的最终“e”(只是一个bencode字典 - 所有torrent文件都以“d”开头,以“e”结尾。

这是二进制数据,所以在填写torrentstub []时必须这样读。

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

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

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

我假设您有代码来执行实际的SHA1。你在做什么平台?

答案 1 :(得分:0)

.torrent规范是freely available,应该可以帮助您轻松理解文件格式。您需要做的就是使用info密钥的内容来获取信息哈希值。