Java Encode SHA-1 matriz de bytes
Pergunta
Eu tenho uma matriz de bytes SHA-1 que eu gostaria de usar em uma solicitação GET. Eu preciso para codificar isso. URLEncoder
espera uma corda, e se eu criar uma cadeia do mesmo e, em seguida, codificá-lo, ele fica corrompido?
Para esclarecer, isso é meio um acompanhamento para uma outra pergunta da mina. (Request Bitorrent Tracker) posso obter o valor como uma string hex, mas que não é reconhecido pela rastreador. Por outro lado, marca de resposta codificado fornecido retorno 200 OK.
Então eu preciso para converter a representação hexadecimal que eu tenho:
9a81333c1b16e4a83c10f3052c1590aadf5e2e20
em forma codificada
%9A%813%3C%1B%16%E4%A8%3C%10%F3%05%2C%15%90%AA%DF%5E.%20
Solução
Pergunta foi editado enquanto eu estava respondendo, a seguir é o código adicional e deve funcionar (com o meu código de conversão hex):
//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);
}
Você vai precisar para converter os bytes brutos para caracteres hexadecimais ou qualquer codificação-friendly URL que eles estão usando. Base32 ou Base64 codificações são possíveis, mas caracteres hexadecimais retas é o mais comum. URLEncoder não é necessário para essa sequência porque ele não deve conter quaisquer caracteres que exigiriam URL Encoding para o formato NN%.
A seguir irá converter bytes para um hash (SHA-1, MD5SUM, etc.) para uma cadeia hexadecimal:
/** 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);
}
Este código é bastante otimizado e rápido, e eu estou usando-o para o meu próprio SHA-1 byte codificação. Note que você pode precisar converter maiúsculas para minúsculas com o String.toLowerCase () método, dependendo de qual forma o servidor aceita.
Outras dicas
Isso depende do que o destinatário da espera de solicitação. Eu imaginaria que poderia ser uma representação hexadecimal dos bytes em seu hash. Uma corda provavelmente não seria a melhor idéia, porque a matriz de hash provavelmente irá conter valores de caracteres não-imprimíveis.
Eu iterar sobre o array e usar Integer.toHexValue () para converter os bytes em hexadecimal.
SHA1 é em formato hexadecimal [0-9a-f], não deve haver necessidade de URLEncode-lo.
Use Apache Commons-Codec para todas as suas necessidades de codificação / decodificação (exceto ASN .1, que é um pé no saco)