【问题标题】:From string to hex MD5 hash and back从字符串到十六进制 MD5 哈希并返回
【发布时间】:2011-03-02 16:12:10
【问题描述】:

我在 java 中有这个伪代码:

bytes[] hash = MD5.hash("example");

String hexString = toHexString(hash); //This returns something like a0394dbe93f

bytes[] hexBytes = hexString.getBytes("UTF-8");

现在,hexBytes[]hash[] 是不同的。

我知道我做错了什么,因为hash.length() 是 16,hexBytes.length() 是 32。也许它与 java 使用 Unicode 字符有关(这里只是一个疯狂的猜测)。

无论如何,问题是:如何从hexString 中获取原始的hash[] 数组。

如果你想看的话,完整的代码在这里(大约 40 LOC)http://gist.github.com/434466

该代码的输出是:

16
[-24, 32, -69, 74, -70, 90, -41, 76, 90, 111, -15, -84, -95, 102, 65, -10]
32
[101, 56, 50, 48, 98, 98, 52, 97, 98, 97, 53, 97, 100, 55, 52, 99, 53, 97, 54, 102, 102, 49, 97, 99, 97, 49, 54, 54, 52, 49, 102, 54]

非常感谢!

【问题讨论】:

    标签: java hash md5 hex


    【解决方案1】:

    您尚未显示toHexString,但基本上您需要反向等效项 - 查找名为 fromHexString 或类似名称的方法。

    基本上String.getBytes() 执行正常编码(在本例中为 UTF-8)。您希望将文本(任意二进制数据的文本表示)有效解码byte[]

    Apache Commons Codec 有适当的方法 - API 并不理想,但它可以工作:

    byte[] data = ...;
    String hex = Hex.encodeHexString(data);
    ...
    
    byte[] decoded = (byte[]) Hex.decode(hex);
    

    【讨论】:

    • 代码在我链接的要点中gist.github.com/434466(虽然名称不同)。谢谢,我会研究一下 Apache Commons
    • 只是好奇……为什么说 API 不理想?
    • @Pablo:理想情况下,应该有一个 Hex.decode 方法接受一个字符串并返回一个强类型的字节数组。 Object decode(Object) 签名很烦人。
    • 哦,我刚下载了最后一个版本,取了一个char数组,返回一个byte数组。
    • @Pablo:有一个重载可以做到这一点,是的 - 但是为了这个而不得不转换为 char 数组很烦人。
    【解决方案2】:

    您只是使用 hexString.getBytes("UTF-8"); 获取十六进制字符串的字节,而不是将十六进制数字转换为其字节值。

    也就是说,您需要编写您的 toHexString 函数的反面。 您的 toHexString 可能应该确保格式化低于 10 到 2 位数字的值,例如字节 9 以 "09" 而不是 "9" 结尾。

    【讨论】:

      【解决方案3】:

      getBytes() 不解析十六进制字符,它处理字符编码。换句话说,它不会将'0A'变成0x0A,而是变成0x30 0x41,因为这就是字符'0'和'A'的编码方式。您希望 Integer.parseInt(String, radix) 在您的函数中使用 radix==16。

      【讨论】:

        【解决方案4】:

        如果您不想使用库,可以使用我的十六进制解码器版本来做到这一点,

        byte[] hexBytes = dehexify(hexString);
        
        public static byte[] dehexify(String hexString) {
            if (hexString.length()%2 == 1)
                throw new IllegalArgumentException("Invalid length");       
            int len = hexString.length()/2;
            byte[] bytes = new byte[len];
            for (int i=0; i<len; i++) {
                int index = i*2;
                bytes[i] = (byte)Integer.parseInt(hexString.substring(index, index+2), 16);
            }
            return bytes;
        }
        

        【讨论】:

          猜你喜欢
          • 2020-12-28
          • 1970-01-01
          • 2011-05-18
          • 2011-07-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-19
          • 2014-07-24
          相关资源
          最近更新 更多