我正在使用C ++来解析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
有人知道我在这里做错了什么吗?问题可能在于文件末尾的不可读性吗?我是否需要先将其解析为十六进制或其他内容?
答案 0 :(得分: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
你想干这一部分:
d6:pieces20:....................4:name4:test12:piece lengthi1024ee
有关bencoding的更多信息,请参阅BEP3。
答案 1 :(得分:1)
SHA1计算与您编写的内容一样简单,或多或少。如果您从库函数中得到错误的答案,则错误可能在您正在提供的数据中。
我不能说你已经完成的torrent文件准备工作,但我确实看到了一些问题。如果您将重新访问SHA1 docs,请注意SHA1函数永远不需要自己的摘要长度作为参数。接下来,您将非常确定您正在使用的技术来读取文件的内容是忠实地提取确切的字节,没有翻译。
不太重要的样式建议:将第三个参数用于SHA1。一般规则,最好避免库中的静态存储。总是喜欢提供自己的缓冲区。此外,如果您的打印功能中有20个硬编码,那么这就是您一直在调情的消化长度常数的绝佳位置。