1

仕様によると: http://wiki.theory.org/BitTorrentSpecification

info_hash: Metainfo ファイルの情報キーの値の urlencoded 20 バイト SHA1 ハッシュ。上記の情報キーの定義を考えると、値はコード化された辞書になることに注意してください。

torrentMap は私の辞書です。info別の辞書であるキーを取得し、ハッシュを計算してURLencodeそれを計算します。

invalid 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();
}
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 に答える