我有一个字节数组。 我希望将该数组的每个字节String转换为相应的十六进制值。

Java中是否有将字节数组转换为十六进制的函数?


当前回答

如果你喜欢流,这里有一个格式-连接方法的单表达式版本:

String hex = IntStream.range(0, bytes.length)
                      .map(i -> bytes[i] & 0xff)
                      .mapToObj(b -> String.format("%02x", b))
                      .collect(Collectors.joining());

遗憾的是没有类似Arrays::streamUnsignedBytes这样的方法。

其他回答

如果你喜欢流,这里有一个格式-连接方法的单表达式版本:

String hex = IntStream.range(0, bytes.length)
                      .map(i -> bytes[i] & 0xff)
                      .mapToObj(b -> String.format("%02x", b))
                      .collect(Collectors.joining());

遗憾的是没有类似Arrays::streamUnsignedBytes这样的方法。

其他人已经报道了一般情况。但是如果你有一个已知形式的字节数组,例如MAC地址,那么你可以:

byte[] mac = { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 };

String str = String.format("%02X:%02X:%02X:%02X:%02X:%02X",
                           mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 
    byte[] bytes = {-1, 0, 1, 2, 3 };
    StringBuilder sb = new StringBuilder();
    for (byte b : bytes) {
        sb.append(String.format("%02X ", b));
    }
    System.out.println(sb.toString());
    // prints "FF 00 01 02 03 "

另请参阅

java.util.Formatter语法 %(旗帜)(宽度)转换 标记'0' -结果将被填充为零 宽度2 转换'X' -结果被格式化为十六进制整数,大写


看看问题的文本,也有可能是这样要求的:

    String[] arr = {"-1", "0", "10", "20" };
    for (int i = 0; i < arr.length; i++) {
        arr[i] = String.format("%02x", Byte.parseByte(arr[i]));
    }
    System.out.println(java.util.Arrays.toString(arr));
    // prints "[ff, 00, 0a, 14]"

这里的几个答案使用Integer.toHexString(int);这是可行的,但有一些注意事项。由于形参是int型,因此对byte参数执行扩大原语转换,这涉及到符号扩展。

    byte b = -1;
    System.out.println(Integer.toHexString(b));
    // prints "ffffffff"

在Java中有符号的8位字节被符号扩展为32位整型。为了有效地撤销这个符号扩展,可以使用0xFF来屏蔽字节。

    byte b = -1;
    System.out.println(Integer.toHexString(b & 0xFF));
    // prints "ff"

使用toHexString的另一个问题是它不会用零填充:

    byte b = 10;
    System.out.println(Integer.toHexString(b & 0xFF));
    // prints "a"

这两个因素结合起来应该形成字符串。格式解决方案更佳。

参考文献

整型类型和值 对于字节,从-128到127,包括 JLS 5.1.2扩大原语转换

这是我迄今为止发现的运行最快的代码。我在23ms内运行了109015个长度为32的字节数组。我在VM上运行它,所以它在裸机上可能会运行得更快。

public static final char[] HEX_DIGITS =         {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

public static char[] encodeHex( final byte[] data ){
    final int l = data.length;
    final char[] out = new char[l<<1];
    for( int i=0,j=0; i<l; i++ ){
        out[j++] = HEX_DIGITS[(0xF0 & data[i]) >>> 4];
        out[j++] = HEX_DIGITS[0x0F & data[i]];
    }
    return out;
}

然后你就可以做了

String s = new String( encodeHex(myByteArray) );
BigInteger n = new BigInteger(byteArray);
String hexa = n.toString(16);