Domanda

Ho un array di byte SHA-1 che vorrei utilizzare in una richiesta GET. Devo codificarlo. URLEncoder si aspetta una stringa e se creo una stringa e la codifico, si corrompe?

Per chiarire, questo è un po 'il seguito di un'altra mia domanda. ( Richiesta tracker bitorrent ) Posso ottenere il valore come una stringa esadecimale, ma questo non è riconosciuto dal tracker. D'altra parte, il segno di risposta codificato ha fornito return 200 OK.

Quindi devo convertire la rappresentazione esadecimale che ho ottenuto:

9a81333c1b16e4a83c10f3052c1590aadf5e2e20

in forma codificata

%9A%813%3C%1B%16%E4%A8%3C%10%F3%05%2C%15%90%AA%DF%5E.%20
È stato utile?

Soluzione

La domanda è stata modificata mentre rispondevo, di seguito è riportato il codice AGGIUNTIVO e dovrebbe funzionare (con il mio codice di conversione esadecimale):

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

Dovrai convertire i byte non elaborati in caratteri esadecimali o in qualsiasi codifica compatibile con URL che stanno utilizzando. Sono possibili codifiche Base32 o Base64, ma i caratteri esadecimali diritti sono i più comuni. URLEncoder non è necessario per questa stringa, poiché non deve contenere caratteri che richiedono la codifica URL nel formato% NN.

Il seguente convertirà i byte per un hash (SHA-1, MD5SUM, ecc.) in una stringa esadecimale:

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

Questo codice è abbastanza ottimizzato e veloce, e lo sto usando per la mia codifica di byte SHA-1. Nota che potresti dover convertire maiuscole in minuscole con il metodo String.toLowerCase (), a seconda della forma accettata dal server.

Altri suggerimenti

Questo dipende da cosa si aspetta il destinatario della tua richiesta. Immagino che potrebbe essere una rappresentazione esadecimale dei byte nel tuo hash. Una stringa non sarebbe probabilmente la migliore idea, poiché l'array hash conterrà molto probabilmente valori di caratteri non stampabili.

Esaminerei l'array e userei Integer.toHexValue () per convertire i byte in esadecimale.

SHA1 è in formato esadecimale [0-9a-f], non dovrebbe essere necessario URLEncode.

Usa Apache Commons-Codec per tutte le tue esigenze di codifica / decodifica (tranne ASN .1, che è un dolore nel culo)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top