2013-11-03 59 views
4

我用C++來解析torrent文件的信息散列的信息哈希,和我有麻煩相比得到一個「正確」的散列值這個網站:計算torrent文件

http://i-tools.org/torrent

我已經構建了一個非常簡單的玩具示例,以確保我有基本的權利。

我崇高打開一個文件的.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 

而且我遇到了這個outpu T:

4d0ca7e1599fbb658d886bddf3436e6543f58a8b 

當我期待這樣的輸出:

14FFE5DD23188FD5CB53A1D47F1289DB70ABF31E 

有誰知道我可能是做錯了什麼?問題在於文件末尾的不可讀性?我是否需要首先將它解析爲十六進制或其他內容?

回答

8

確保在文件末尾沒有換行符,也可以確保它以'e'結尾。

torrent文件的信息哈希是來自.torrent文件的信息部分(以bencoded形式)的SHA-1哈希。實際上,您需要解碼文件(它被編碼)並記住與「信息」鍵關聯的值的內容開始和結束的字節偏移量。這就是你需要散列的字節範圍。

例如,如果是這樣的torrent文件:

d4:infod6:pieces20:....................4:name4:test12:piece lengthi1024ee8:announce27:http://tracker.com/announcee 

你婉只是哈希本節:

d6:pieces20:....................4:name4:test12:piece lengthi1024ee 

有關bencoding的更多信息,請參閱BEP3

+0

我很確定問題是換行符!謝謝! 上面的例子是一個玩具的例子,我刪除了除了信息詞典以外的torrent文件中的所有內容。 – Ethan

+2

請注意,Arvid給出的示例torrent文件,根字典和信息字典都是未排序的。根據bencode規範,必須對字典進行排序。但是,由於某種原因信息字典未被分類時,約定的約定是將信息字典原始數據散列(未排序),如上面的Arvid所解釋的。 – Encombe

+3

是的,好點。它也可以作爲一個例子,即使當bencoded字典被錯誤地排序時,info-hash仍然是逐字形式的散列。某些客戶端(用於)在散列之前進行解碼和重新編碼,在這種情況下會導致錯誤的信息散列。 – Arvid

1

SHA1的計算和你寫的一樣簡單,或多或少。如果您從庫函數中得到錯誤答案,那麼錯誤可能出現在您提供的數據中。

我不能說你做過的torrent文件準備工作,但我確實看到一些問題。如果您將重新訪問SHA1 docs,請注意SHA1函數從不要求自己的摘要長度作爲參數。接下來,您需要非常確定您正在使用的讀取文件內容的技巧是忠實地吮吸確切的字節,而不是翻譯。

不太重要的風格建議:使用SHA1的第三個參數。一般規則,最好避免庫中的靜態存儲。總是喜歡提供自己的緩衝區。此外,如果您的打印功能中有20位硬編碼,那麼這是您一直在調情的摘要長度不變的絕妙之處。

+0

誰完全誤讀,並認爲傳遞給SHA1的長度是爲接收陣列! 我修正了,顯然我得到了不同的散列,但它仍然不是正確的一個.... 我認爲問題是與我的文件或我沒有做的torrent文件。我修剪前面的種子文件與我爲了獲得不同結果而進入該網頁的文件是一樣的,所以它從根本上沒有損壞或任何東西。我更改了發佈的代碼以反映更改。 – Ethan