2010-06-11 49 views
1

我有这样的伪代码在java中:从字符串为十六进制的MD5哈希和背部

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] 

非常感谢!

回答

2

您是刚开始的十六进制字符串的字节与hexString.getBytes("UTF-8");,不转换十六进制数字到他们的字节值。

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

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); 
+0

代码是我挂HTTP要点://gist.github .com/434466(尽管名称不同)。谢谢,我会考虑Apache Commons – 2010-06-11 13:49:02

+0

只是好奇......你为什么说API不理想? – 2010-06-11 13:55:58

+0

@Pablo:理想情况下,应该有一个采用 字符串并返回强类型的字节数组的Hex.decode方法。 “Object decode(Object)'签名很烦人。 – 2010-06-11 14:26:16

1

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

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; 
} 
相关问题