2012-11-03 38 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