1

according to the specification: http://wiki.theory.org/BitTorrentSpecification

info_hash: urlencoded 20-byte SHA1 hash of the value of the info key from the Metainfo file. Note that the value will be a bencoded dictionary, given the definition of the info key above.

torrentMap is my dictionary, I get the info key which is another dictionary, I calculate the hash and I URLencode it.

But I always get an invalid info_hash message when I try to send it to the tracker.

This is my code:

    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();
}
4

1 回答 1

0

这几乎肯定是问题所在:

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

您将要散列的是 的值的Java 二进制序列化格式torrentMap.get("info")。我很难相信所有的 BitTorrent 程序都应该知道这一点。

从规范中我并不清楚“info”键的值是什么意思,但是您需要找出其他方法将其转换为字节数组。如果它是一个字符串,我希望有一些明确指定的编码(例如 UTF-8)。如果它已经是二进制数据,则直接使用该字节数组。

编辑:实际上,根据您的报价,听起来该值将是一个“编码字典”,看起来它将是一个字符串。在散列可供抓取之前,您打算如何对该字符串进行编码(例如,这听起来可能包括不在 ASCII 中的值)。如果您的示例字符串都是 ASCII,那么使用“ASCII”和“UTF-8”作为编码名称String.getBytes(...)无论如何都会给出相同的结果,当然......

于 2012-11-04T00:05:32.883 回答