我有一个SHA-1字节数组,我想在GET请求中使用它。我需要对此进行编码。 URLEncoder
需要一个字符串,如果我创建一个字符串然后对其进行编码,它会被破坏吗?
澄清一下,这有点是我的另一个问题的后续行动。 (Bitorrent Tracker Request)我可以将值作为十六进制字符串获取,但跟踪器无法识别。另一方面,提供的编码答案标记返回200 OK。
所以我需要转换我得到的十六进制表示法:
9a81333c1b16e4a83c10f3052c1590aadf5e2e20
编码形式
%9A%813%3C%1B%16%E4%A8%3C%10%F3%05%2C%15%90%AA%DF%5E.%20
答案 0 :(得分:3)
我在回复时编辑了问题,以下是附加代码,应该可以使用(使用我的十六进制转换代码):
//Inefficient, but functional, does not test if input is in hex charset, so somewhat unsafe
//NOT tested, but should be functional
public static String encodeURL(String hexString) throws Exception {
if(hexString==null || hexString.isEmpty()){
return "";
}
if(hexString.length()%2 != 0){
throw new Exception("String is not hex, length NOT divisible by 2: "+hexString);
}
int len = hexString.length();
char[] output = new char[len+len/2];
int i=0;
int j=0;
while(i<len){
output[j++]='%';
output[j++]=hexString.charAt(i++);
output[j++]=hexString.charAt(i++);
}
return new String(output);
}
您需要将原始字节转换为十六进制字符或他们正在使用的任何URL友好编码。 Base32或Base64编码是可能的,但直接的十六进制字符是最常见的。此字符串不需要URLEncoder,因为它不应包含任何需要URL编码为%NN格式的字符。
下面将把哈希值(SHA-1,MD5SUM等)的字节转换为十六进制字符串:
/** Lookup table: character for a half-byte */
static final char[] CHAR_FOR_BYTE = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
/** Encode byte data as a hex string... hex chars are UPPERCASE*/
public static String encode(byte[] data){
if(data == null || data.length==0){
return "";
}
char[] store = new char[data.length*2];
for(int i=0; i<data.length; i++){
final int val = (data[i]&0xFF);
final int charLoc=i<<1;
store[charLoc]=CHAR_FOR_BYTE[val>>>4];
store[charLoc+1]=CHAR_FOR_BYTE[val&0x0F];
}
return new String(store);
}
这段代码相当优化且速度很快,我将它用于我自己的SHA-1字节编码。请注意,您可能需要使用String.toLowerCase()方法将大写转换为小写,具体取决于服务器接受的形式。
答案 1 :(得分:0)
这取决于您的请求的收件人期望的内容。 我想它可能是哈希中字节的十六进制表示。字符串可能不是最好的主意,因为哈希数组很可能包含不可打印的字符值。
我迭代数组并使用Integer.toHexValue()将字节转换为十六进制。
答案 2 :(得分:0)
SHA1是十六进制格式[0-9a-f],不需要URLEncode它。
答案 3 :(得分:0)
使用Apache Commons-Codec来满足您的所有编码/解码需求(除了ASN.1,这是一个痛苦的屁股)