2012-11-03 39 views
1

根據規範:http://wiki.theory.org/BitTorrentSpecification無效info_hash(爪哇BT客戶端)

info_hash:從進行了urlencoded元信息文件的信息項的值的20個字節的SHA1哈希。請注意,根據上面的信息鍵的定義,該值將是一個帶有空格的字典。

torrentMap是我的字典,我得到了「信息」鍵,這是另一個字典,我計算哈希和我的URL編碼它。 ,但當我嘗試將其發送給跟蹤器時,我總是收到無效的info_hash消息。

這是我的代碼:

public String GetInfo_hash() { 
    String info_hash = ""; 

    ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
    ObjectOutput out = null; 
    try { 
     out = new ObjectOutputStream(bos); 
     out.writeObject(torrentMap.get("info")); 
     byte[] bytes = bos.toByteArray();  //Map => byte[] 

     MessageDigest md = MessageDigest.getInstance("SHA1"); 
     info_hash = urlencode(md.digest(bytes)); //Hashing and URLEncoding 

     out.close(); 
     bos.close(); 

    } catch (Exception ex) {  } 

    return info_hash; 
} 

private String urlencode(byte[] bs) { 
    StringBuffer sb = new StringBuffer(bs.length * 3); 
    for (int i = 0; i < bs.length; i++) { 
     int c = bs[i] & 0xFF; 
     sb.append('%'); 
     if (c < 16) { 
      sb.append('0'); 
     } 
     sb.append(Integer.toHexString(c)); 
    } 
    return sb.toString(); 
} 

回答

0

這是幾乎可以肯定的問題:

out = new ObjectOutputStream(bos); 
out.writeObject(torrentMap.get("info")); 

什麼你將成爲哈希是價值的的Java二進制序列化格式torrentMap.get("info")。我發現很難相信所有的BitTorrent程序都是爲了瞭解這一點。

從規範中我不會立即明白「info」鍵的價值是什麼,但是您需要制定一些其他方法將它轉換爲字節數組。如果它是一個字符串,我期望一些精心指定的編碼(例如UTF-8)。如果它已經是二進制數據,那麼直接使用該字節數組。

編輯:其實,它聽起來像值將是一個「bencoded字典」根據您的報價,它看起來像它將是一個字符串。相當於如何在散列之前編碼該字符串(聽起來像它可能包含不是ASCII碼的值),然後再進行格式化。如果您的示例字符串都是ASCII,那麼使用「ASCII」和「UTF-8」作爲String.getBytes(...)的編碼名稱將會給出相同的結果,當然...

+0

** torrentMap.get(「info」) **返回一個Object,它可以轉換成一個HashMap。根據你說的我改變方法爲:**返回urlencode(torrentMap.get(「info」)。toString()。getBytes(Charset.forName(「UTF-8」))); **但它仍然給我錯了:( – Simone

+0

@Simone:那麼如果它真的*是一個'HashMap',你需要以bencoding的形式將它變成一個'String' - 因爲這就是哈希值。目前還不清楚你是否試圖創建你自己的BT API從零開始,或者修改現有的API,但你需要*本地編碼支持 –

+0

我下載了Snark客戶端,並且我解決了所有的問題^^ – Simone