从字符串到十六进制MD5哈希并返回

时间:2010-06-11 13:29:13

标签: java hash md5 hex

我在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.也许它与使用Unicode for chars的java有关(这里只是一个疯狂的猜测)。

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

如果你想看一下整个代码就在这里(它是~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]

非常感谢!

4 个答案:

答案 0 :(得分:2)

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

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

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

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

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

答案 1 :(得分:2)

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

也就是说,您需要编写toHexString函数的反向。 您的toHexString应该确保格式化低于10到2位的值,例如字节9最终为“09”而不是“9”。

答案 2 :(得分:1)

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

答案 3 :(得分:1)

如果您不想使用库,可以使用我的十六进制解码器版本来完成此操作,

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