【问题标题】:Java Encode SHA-1 Byte ArrayJava 编码 SHA-1 字节数组
【发布时间】:2009-06-19 20:11:42
【问题描述】:

我有一个 SHA-1 字节数组,我想在 GET 请求中使用它。我需要对此进行编码。 URLEncoder 需要一个字符串,如果我创建一个字符串然后对其进行编码,它会损坏吗?

为了澄清,这有点像我的另一个问题的后续行动。 (Bitorrent Tracker Request) 我可以将值作为十六进制字符串获取,但跟踪器无法识别。另一方面,提供的编码答案标记返回 200 OK。

所以我需要转换我得到的十六进制表示:

9a81333c1b16e4a83c10f3052c1590aadf5e2e20

编码形式

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

【问题讨论】:

  • 我已经编辑了我的帖子以包含新代码来回答您编辑的问题。

标签: java encode sha


【解决方案1】:

问题在我回复时被编辑,以下是附加代码,应该可以工作(使用我的十六进制转换代码):

//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() 方法将大写转换为小写,具体取决于服务器接受的格式。

【讨论】:

    【解决方案2】:

    这取决于您的请求的接收者期望什么。 我想它可能是哈希中字节的十六进制表示。字符串可能不是最好的主意,因为哈希数组很可能包含不可打印的字符值。

    我会遍历数组并使用 Integer.toHexValue() 将字节转换为十六进制。

    【讨论】:

      【解决方案3】:

      SHA1是十六进制格式[0-9a-f],应该不需要URLEncode了。

      【讨论】:

      • SHA1 不会自动采用十六进制格式。所有 SHA1 结果都是一个字节数组。您可以将这些字节编码为十六进制。
      【解决方案4】:

      使用Apache Commons-Codec 满足您的所有编码/解码需求(ASN.1 除外,这很麻烦)

      【讨论】:

        猜你喜欢
        • 2010-12-03
        • 2013-08-24
        • 1970-01-01
        • 2012-02-22
        • 2015-04-09
        • 2010-10-18
        • 1970-01-01
        • 2018-11-08
        • 1970-01-01
        相关资源
        最近更新 更多