协慌网

登录 贡献 社区

如何在 Java 中将字节数组转换为十六进制字符串?

我有一个用十六进制数字填充并打印的字节数组,简单的方法是毫无意义的,因为有许多不可打印的元素。我需要的是以下形式的确切十六进制代码: 3a5f771c

答案

通过这里的讨论,尤其是这个答案,这是我当前使用的功能:

private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) {
    char[] hexChars = new char[bytes.length * 2];
    for (int j = 0; j < bytes.length; j++) {
        int v = bytes[j] & 0xFF;
        hexChars[j * 2] = HEX_ARRAY[v >>> 4];
        hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
    }
    return new String(hexChars);
}

我自己的小型基准测试(一百万个字节,一千个字节,256 个字节,一千万次)表明,它比任何其他替代方案都要快得多,大约是长阵列的一半。与我从中得到的答案相比,转换为按位运算 - 正如讨论中所建议的 -- 长数组的使用时间减少了约 20%。 (编辑:当我说它比替代方法更快时,是指讨论中提供的替代代码。性能等效于 Commons Codec,后者使用非常相似的代码。)

关于 Java 9 紧凑字符串的 2k20 版本:

private static final byte[] HEX_ARRAY = "0123456789ABCDEF".getBytes(StandardCharsets.US_ASCII);
public static String bytesToHex(byte[] bytes) {
    byte[] hexChars = new byte[bytes.length * 2];
    for (int j = 0; j < bytes.length; j++) {
        int v = bytes[j] & 0xFF;
        hexChars[j * 2] = HEX_ARRAY[v >>> 4];
        hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
    }
    return new String(hexChars, StandardCharsets.UTF_8);
}

Apache Commons Codec库具有一个Hex类,用于执行此类工作。

import org.apache.commons.codec.binary.Hex;

String foo = "I am a string";
byte[] bytes = foo.getBytes();
System.out.println( Hex.encodeHexString( bytes ) );

javax.xml.bind.DatatypeConverter.printHexBinary() byte[]转换为十六进制字符串的便捷方法,它是Java XML 绑定体系结构(JAXB)的一部分。 DatatypeConverter类还包括许多其他有用的数据处理方法。

在 Java 8 和更早版本中,JAXB 是 Java 标准库的一部分。为了将所有 Java EE 软件包移至它们自己的库中,此功能在Java 9已弃用,在 Java 11中已删除。这是一个漫长的故事。现在, javax.xml.bind不存在,如果要使用包含DatatypeConverter JAXB,则需要从 Maven 安装 JAXB APIJAXB Runtime。

用法示例:

byte bytes[] = {(byte)0, (byte)0, (byte)134, (byte)0, (byte)61};
String hex = javax.xml.bind.DatatypeConverter.printHexBinary(bytes);

将导致:

000086003D

这个答案与相同。