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

Java 从字符串到十六进制MD5哈希并返回,java,hash,md5,hex,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.len

我用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)

该代码的输出为:

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]

非常感谢

您没有显示
到hexstring
,但基本上您需要相反的等价物-查找名为
的方法fromHexString
或类似的方法

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

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

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

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

您没有显示
toHexString
,但基本上您需要相反的等价物-查找名为
fromHexString
或类似方法

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

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

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

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

通过
hexString.getBytes(“UTF-8”),不将十六进制数字转换为字节值

也就是说,您需要将
函数的反面写入hexstring
函数。
您的toHexString可能应该确保将值的格式设置为10到2位以下,例如,字节9以“09”而不是“9”结尾。

您只是通过
hexString.getBytes(“UTF-8”)获取十六进制字符串的字节,不将十六进制数字转换为字节值

也就是说,您需要将
函数的反面写入hexstring
函数。
您的toHexString可能应该确保将值的格式设置为10到2位以下,例如字节9以“09”而不是“9”结尾。

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

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

如果您不想使用库,下面是如何使用我的十六进制解码器版本

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;
}
byte[]hexBytes=dehexify(hexString);
公共静态字节[]dehexify(字符串hexString){
if(hexString.length()%2==1)
抛出新的IllegalArgumentException(“无效长度”);
int len=hexString.length()/2;
字节[]字节=新字节[len];

对于(int i=0;i如果您不想使用库,下面是如何使用我的十六进制解码器版本

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;
}
byte[]hexBytes=dehexify(hexString);
公共静态字节[]dehexify(字符串hexString){
if(hexString.length()%2==1)
抛出新的IllegalArgumentException(“无效长度”);
int len=hexString.length()/2;
字节[]字节=新字节[len];

对于(int i=0;代码在我链接的要点中(名称不同)。谢谢,我将研究Apache Commons只是好奇…为什么你说API不理想?@Pablo:理想情况下应该有一个Hex.decode方法,获取字符串并返回字节数组,强类型。
对象解码(Object)
签名很烦人。哦,我刚下载了上一个版本,获取了一个字符数组并返回了一个字节数组。@Pablo:有一个重载可以做到这一点,是的-但是仅仅为了这个就必须转换成字符数组,这很烦人。代码在我链接的要点中(名称不同)。谢谢,我会研究Apache Commons只是好奇…为什么你说API不理想?@Pablo:理想情况下,应该有一个十六进制解码方法,获取字符串并返回一个强类型的字节数组。
对象解码(Object)
签名很烦人。哦,我刚下载了上一个版本,获取了一个字符数组并返回了一个字节数组。@Pablo:有一个重载可以做到这一点,是的-但是仅仅为了这个就必须转换成字符数组,这很烦人。