Pregunta

Tengo una matriz de bytes SHA-1 que me gustaría usar en una solicitud GET. Necesito codificar esto. URLEncoder espera una cadena, y si creo una cadena y luego la codifico, ¿se corrompe?

Para aclarar, esto es un seguimiento de otra pregunta mía. ( Solicitud de seguimiento de Bitorrent ) Puedo obtener el valor como una cadena hexadecimal, pero eso no es reconocido por el rastreador. Por otro lado, la marca de respuesta codificada proporcionó 200 OK.

Entonces necesito convertir la representación hexadecimal que obtuve:

9a81333c1b16e4a83c10f3052c1590aadf5e2e20

en forma codificada

%9A%813%3C%1B%16%E4%A8%3C%10%F3%05%2C%15%90%AA%DF%5E.%20
¿Fue útil?

Solución

La pregunta se editó mientras respondía, el siguiente es un código ADICIONAL y debería funcionar (con mi código de conversión hexadecimal):

//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);
}

Deberá convertir los bytes sin formato a caracteres hexadecimales o cualquier codificación compatible con URL que estén utilizando. Las codificaciones Base32 o Base64 son posibles, pero los caracteres hexadecimales rectos son los más comunes. URLEncoder no es necesario para esta cadena, porque no debe contener ningún carácter que requiera la codificación de URL al formato% NN.

Lo siguiente convertirá bytes para un hash (SHA-1, MD5SUM, etc.) en una cadena 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 está bastante optimizado y es rápido, y lo estoy usando para mi propia codificación de bytes SHA-1. Tenga en cuenta que es posible que necesite convertir mayúsculas a minúsculas con el método String.toLowerCase (), según la forma que acepte el servidor.

Otros consejos

Esto depende de lo que espera el destinatario de su solicitud. Me imagino que podría ser una representación hexadecimal de los bytes en su hash. Una cadena probablemente no sería la mejor idea, porque la matriz hash probablemente contendrá valores de caracteres no imprimibles.

Me gustaría iterar sobre la matriz y usar Integer.toHexValue () para convertir los bytes a hexadecimal.

SHA1 está en formato hexadecimal [0-9a-f], no debería haber necesidad de URLEncodearlo.

Utilice Apache Commons-Codec para todas sus necesidades de codificación / decodificación (excepto ASN .1, que es un dolor en el culo)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top