문제

GET 요청에 사용하고 싶은 SHA-1 바이트 배열이 있습니다. 나는 이것을 인코딩해야한다. URLEncoder 문자열을 기대하고 문자열을 만들고 인코딩하면 손상 되나요?

명확히하기 위해, 이것은 내 다른 질문에 대한 후속 조치입니다. (BITORRENT 추적기 요청) 값을 육각 문자열로 얻을 수 있지만 추적기는 인식하지 못합니다. 반면, 인코딩 된 답변 마크는 Return 200 OK를 제공했습니다.

그래서 나는 내가 얻은 16 진 진술을 변환해야합니다.

9a81333c1b16e4a83c10f3052c1590aadf5e2e20

인코딩 된 형태로

%9A%813%3C%1B%16%E4%A8%3C%10%F3%05%2C%15%90%AA%DF%5E.%20
도움이 되었습니까?

해결책

응답하는 동안 질문이 편집되었으며 다음은 추가 코드이며 (16 진수 변환 코드와 함께) 작동해야합니다.

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

원시 바이트를 16 진 문자 또는 사용중인 URL 친화적 인 인코딩으로 변환해야합니다. Base32 또는 Base64 인코딩이 가능하지만 직선형 16 진 문자가 가장 일반적입니다. 이 문자열에는 Urlencoder가 필요하지 않습니다. URL이 %NN 형식으로 인코딩 해야하는 문자가 포함되어 있지 않아야하기 때문입니다.

아래는 해시 (SHA-1, MD5SUM 등)의 바이트를 16 진수로 변환합니다.

/** 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 () 메소드를 사용하여 대문자를 소문자로 변환해야 할 수도 있습니다.

다른 팁

이것은 귀하의 요청 수신자가 기대하는 것에 따라 다릅니다. 나는 그것이 당신의 해시에서 바이트를 16 진수하게 표현할 수 있다고 생각합니다. 해시 어레이에는 인쇄 할 수없는 문자 값이 포함될 가능성이 높기 때문에 문자열은 아마도 최선의 아이디어가 아닐 것입니다.

배열을 반복하고 Integer.toHexValue ()를 사용하여 바이트를 16 진로 변환합니다.

SHA1은 16 진 형식 [0-9A-F]이며 URLENCODE를 필요로하지 않아야합니다.

사용 Apache Commons-Codec 모든 인코딩/디코딩 요구에 대해 (ASN.1 제외, 이것은 엉덩이의 고통입니다)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top