我在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]
非常感谢!
答案 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;
}