Torrent,使用java查询URL编码

epggiuax  于 2023-02-02  发布在  Java
关注(0)|答案(2)|浏览(137)

我正在写我的Torrent客户端,当我需要发送一个带有信息哈希的GET请求时,我被卡住了。当发送请求时,我需要正确地格式化它。结果,URLEncode与它的名称不匹配,我知道的其他方法不能引导我到达目标。(抱歉英语不好)
我尽量不使用第三方库。
正如我所看到的,我需要"从十六进制表示转换为散列的字节串值",但是我尝试这样做并没有得到想要的结果。
我找到了这些答案和其他一些答案,但它们都是在其他编程语言上,我无法理解,也无法在我的代码中重现它们。link vb.netlink rust
我还找到了Bittorent library,但即使使用它的编码方法,我的程序也没有发生任何变化。
UPD 1:我在bencoding时得到的信息散列:0a85522a2f09e42f3d63a89a0d45e4589f8b904c中所列的数字
以下是我在Wireshark中看到的情况:

https://bt.toloka.to/announce/h=IT5FwgeUF1& (Tracker blocks most countries so if you want to check, use VPN (recomend Netherlands))
&info_hash=%0A%85R%2A%2F%09%E4%2F%3Dc%A8%9A%0DE%E4X%9F%8B%90L
&peer_id=-UT360W-%FE%B5%95%1A%88%0A%DF%97K%E9%FD%23
&port=19708
&uploaded=0
&downloaded=0
&left=16421367202
&corrupt=0
&key=A36E3AE9
&event=stopped
&numwant=0
&compact=1
&no_peer_id=1

它对信息散列进行编码,如下所示:第一节第二节第三节第四节第四节
UPD 2:
我的问题是,我不能实现URL编码。我需要在这里转换这个:
0a85522a2f09e42f3d63a89a0d45e4589f8b904c中所列的数字
变成这样:
第一页第二页第三页第四页
我试图从stackoverflow上的其他答案重写代码,但没有任何明智的成功。

String a = "0a85522a2f09e42f3d63a89a0d45e4589f8b904c";
        
        byte[] hash = a.getBytes(StandardCharsets.UTF_8);
        StringBuilder res = new StringBuilder();

        for(char element : a.toCharArray()){

            if(Character.getNumericValue(element) <= 127){
                char[] result = URLEncoder.encode(String.valueOf(element), String.valueOf(StandardCharsets.UTF_8)).toCharArray();

                if(result[0] == '%'){
                    res.append(toLowerCase(result));
                }else{

                    char[] reinfo = new char[result.length + 1];
                    reinfo[0] = '%';

                    for(int i = 0; i < result.length; i++){
                        reinfo[i + 1] = result[i];
                    }

                    res.append(toLowerCase(reinfo));
                }
            }
        }
iqjalb3h

iqjalb3h1#

信息哈希是20字节的二进制数据,十六进制字符串(40个字符)已经是一种编码形式。因此,最简单的方法是对所有字节进行百分比编码,无论它们是否可以表示为ASCII。
例如,0x8552可以被编码为%85R%85%52,后者空间效率较低,但前者作为起点更容易实现。

e1xvtsh3

e1xvtsh32#

我确实设法用java做了,正如我所注意到的,hash_info中只使用了a-z,A-Z,0-9个字符,所以你所要做的就是把十六进制转换成相应的字母。(有必要的信息here
下面是我得到的代码:

public static String encodeURL(char[] element){
        StringBuilder result = new StringBuilder();

        for(int i = 0; i < element.length; i++){
            result.append(encode( String.valueOf(element[i++]) + element[i]));
        }

        return result.toString();
    }

    private static String encode(String sumChar){

        switch (sumChar){
            case "41": return "A";
            case "42": return "B";
            case "43": return "C";
            case "44": return "D";
            case "45": return "E";
            case "46": return "F";
            case "47": return "G";
            case "48": return "H";
            case "49": return "I";
            case "4A":
            case "4a": return "J";
            case "4B":
            case "4b": return "K";
            case "4C":
            case "4c": return "L";
            case "4D":
            case "4d": return "M";
            case "4E":
            case "4e": return "N";
            case "4F":
            case "4f": return "O";
            case "50": return "P";
            case "51": return "Q";
            case "52": return "R";
            case "53": return "S";
            case "54": return "T";
            case "55": return "U";
            case "56": return "V";
            case "57": return "W";
            case "58": return "X";
            case "59": return "Y";
            case "5A":
            case "5a": return "Z";
            case "61": return "a";
            case "62": return "b";
            case "63": return "c";
            case "64": return "d";
            case "65": return "e";
            case "66": return "f";
            case "67": return "g";
            case "68": return "h";
            case "69": return "i";
            case "6A":
            case "6a": return "j";
            case "6B":
            case "6b": return "k";
            case "6C":
            case "6c": return "l";
            case "6D":
            case "6d": return "m";
            case "6E":
            case "6e": return "n";
            case "6F":
            case "6f": return "o";
            case "70": return "p";
            case "71": return "q";
            case "72": return "r";
            case "73": return "s";
            case "74": return "t";
            case "75": return "u";
            case "76": return "v";
            case "77": return "w";
            case "78": return "x";
            case "79": return "y";
            case "7A":
            case "7a": return "z";

            default: return "%" + sumChar;
        }
    }

输入数据:
0a 85522 a2 f09 e42 f3 d 63 a89 a0 d45 e4589 f8 b 904 c中所列的数字
结果:
第一页第二页第三页第四页
谢谢你给那些想帮忙的人的建议和忠告。

相关问题