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

2022-08-31 04:05:13

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


答案 1

从这里的讨论,特别是这个答案,这是我目前使用的函数:

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字节1000万次)显示它比任何其他替代方案都快得多,大约是长阵列的一半时间。与我的答案相比,切换到按位运算---如讨论中建议的那样,---将长数组的时间缩短了约20%。(编辑:当我说它比替代方案更快时,我的意思是讨论中提供的替代代码。性能等同于Commons编解码器,后者使用非常相似的代码。

2k20 版本,相对于 Java 9 紧凑字符串:

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);
}

答案 2

Apache Commons编解码器库有一个十六进制类,用于执行此类工作。

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

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