使用 Java 将十六进制转储的字符串表示形式转换为字节数组?

2022-08-31 04:35:50

我正在寻找一种将表示十六进制值的长字符串(来自转储)转换为字节数组的方法。

我无法比在这里发布相同问题的人更好地表达它。

但为了保持它的原创性,我会以自己的方式表达它:假设我有一个字符串,我想把它解释为"00A0BF"

byte[] {0x00,0xA0,0xBf}

我该怎么办?

我是一个Java新手,最终使用并注意前导十六进制零。但我认为这是丑陋的,我确信我错过了一些简单的东西。BigInteger


答案 1

更新(2021年) - Java 17现在包括java.util.HexFormat(仅用了25年):

HexFormat.of().parseHex(s)


对于较旧版本的 Java:

这是一个我认为比迄今为止发布的任何解决方案都更好的解决方案:

/* s must be an even-length string. */
public static byte[] hexStringToByteArray(String s) {
    int len = s.length();
    byte[] data = new byte[len / 2];
    for (int i = 0; i < len; i += 2) {
        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                             + Character.digit(s.charAt(i+1), 16));
    }
    return data;
}

为什么它是一个改进的原因:

  • 使用前导零(与 BigInteger 不同)和负字节值(与 Byte.parseByte 不同)时安全

  • 不将字符串转换为 ,也不为每个字节创建 StringBuilder 和 String 对象。char[]

  • 没有可能不可用的库依赖项

如果参数不安全,请随时通过或异常添加参数检查。assert


答案 2

单行:

import javax.xml.bind.DatatypeConverter;

public static String toHexString(byte[] array) {
    return DatatypeConverter.printHexBinary(array);
}

public static byte[] toByteArray(String s) {
    return DatatypeConverter.parseHexBinary(s);
}

警告

  • 在Java 9 Jigsaw中,这不再是(默认)java.se 根集的一部分,因此除非您 java.se.ee 指定--add-modules,否则它将导致ClassNotFoundException(感谢@eckes)
  • 在Android上不可用(感谢您注意到这一点),但是如果您的系统由于某种原因而缺乏源代码,您可以只获取源代码。感谢 @ 提取源代码。Fabianjavax.xmlBert Regelink