Вопрос

У меня есть байтовый массив SHA-1, который я хотел бы использовать в запросе GET. Мне нужно закодировать это. URLEncoder ожидает строку, и если я создаю ее и затем кодирую, она становится поврежденной?

Чтобы уточнить, это своего рода продолжение моего другого вопроса. ( Запрос Bitorrent Tracker ) Я могу получить значение в виде шестнадцатеричной строки, но это не распознается трекер. С другой стороны, кодированная ответная метка возвращает 200 OK.

Итак, мне нужно преобразовать полученное шестнадцатеричное представление:

9a81333c1b16e4a83c10f3052c1590aadf5e2e20

в закодированную форму

%9A%813%3C%1B%16%E4%A8%3C%10%F3%05%2C%15%90%AA%DF%5E.%20
Это было полезно?

Решение

Вопрос был отредактирован, когда я отвечал, ниже приводится ДОПОЛНИТЕЛЬНЫЙ код, который должен работать (с моим шестнадцатеричным кодом преобразования):

//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 (), в зависимости от того, какую форму принимает сервер.

Другие советы

Это зависит от того, что ожидает получатель вашего запроса. Я полагаю, это может быть шестнадцатеричное представление байтов в вашем хэше. Строка, вероятно, не будет лучшей идеей, поскольку хэш-массив, скорее всего, будет содержать непечатаемые символьные значения.

Я бы перебрал массив и использовал бы Integer.toHexValue () для преобразования байтов в шестнадцатеричный формат.

SHA1 имеет шестнадцатеричный формат [0-9a-f], поэтому не нужно его кодировать URLE.

Используйте Apache Commons-Codec для всех ваших потребностей кодирования / декодирования (кроме ASN .1, что является болью в заднице)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top