我有一个字节数组充满十六进制数字和打印它的简单方式是相当没有意义的,因为有许多不可打印的元素。我需要的是精确的十六进制形式:3a5f771c


当前回答

HexFormat是在Java 17中加入的:

String hex = HexFormat.of().formatHex(array);

其他回答

private static String bytesToHexString(byte[] bytes, int length) {
        if (bytes == null || length == 0) return null;

        StringBuilder ret = new StringBuilder(2*length);

        for (int i = 0 ; i < length ; i++) {
            int b;

            b = 0x0f & (bytes[i] >> 4);
            ret.append("0123456789abcdef".charAt(b));

            b = 0x0f & bytes[i];
            ret.append("0123456789abcdef".charAt(b));
        }

        return ret.toString();
    }

这个简单的联机程序适合我 String result = new BigInteger(1, inputBytes).toString(16); EDIT -使用此命令将删除前导0,但在我的用例中它们是有效的。感谢@Voicu指出这一点

Converts bytes data to hex characters

@param bytes byte array to be converted to hex string
@return byte String in hex format

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

最近我必须实现一个十六进制转换器,以十六进制格式将字节流转储到日志中。最初我是用海克斯做的。encodeHex已经在这里讨论过了。

但是如果你想以一种非常美观/可读的方式来表示字节数组,io.netty.buffer库可能是一个很好的用途,因为它打印出十六进制以及其中的字符串,消除了不可打印的字符。

要求是这样的,

0010   56 56 09 35 32 f0 b2 00 50 4c 45 41 53 45 20 52   VV.52...PLEASE R
0020   45 2d 45 4e 54 45 52 20 4c 41 53 54 20 54 52 41   E-ENTER LAST TRA
0030   4e 53 41 43 54 49 4f 4e 00 04                     NSACTION..

使用io.netty.buffer以一种更美观的方式做到这一点的最短方法是

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;

void hexDump(byte[] buf) {
    ByteBuf byteBuf = Unpooled.wrappedBuffer(buf);
    log.trace("Bytes received (Hex)\n" + ByteBufUtil.prettyHexDump(byteBuf.slice()));
}

如果您正在使用maven,请在pom.xml中包含以下依赖项(在netty页面中检查最新版本)

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-buffer</artifactId>
    <version>4.1.68.Final</version>
</dependency>

输出是:

         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000010| 40 40 b3 f3 80 f3 80 f3 80 f1 48 f1 41 f1 4e f1 |@@........H.A.N.|
|00000020| 47 f1 49 f1 4e f1 47 b5 f1 52 f1 4f f1 43 f1 4b |G.I.N.G..R.O.C.K|
|00000030| f3 80 f3 80 41 b4 40 40 f3 80 f3 80 40 f3 80 04 |....A.@@....@...|
+--------+-------------------------------------------------+----------------+

供您参考,使用答案中讨论的方法的长期方法(可能不是最有效的)是:

public static String hexDump(byte[] buf) throws DecoderException
{
    ByteBuffer byteBuf = ByteBuffer.wrap(buf);
    char[] result = Hex.encodeHex(byteBuf);

    String bin = new String(result).toUpperCase();
    String str = new String(Hex.decodeHex(bin), StandardCharsets.UTF_8);

    str = str.replaceAll("[^!-~]", ".");
    StringBuilder out = new StringBuilder();
    int bytes_per_line = 16;

    for (int pos = 0; pos < str.length(); pos += bytes_per_line) {
        out.append(String.format("%04X   ", pos));
        if (2 * (pos + bytes_per_line) >= bin.length()) {
            out.append(String.format("%-" + 2 * bytes_per_line + "s", bin.substring(2 * pos)).replaceAll("..", "$0 "));
        } else {
            out.append(bin.substring(2 * pos, 2 * (pos + bytes_per_line)).replaceAll("..", "$0 "));
        }
        out.append("   ");
        if (pos + bytes_per_line > str.length()) {
            out.append(str.substring(pos));

        } else {
            out.append(str.substring(pos, pos + bytes_per_line));
        }
        out.append("\n");
    }

    return out.toString();
}

如果您正在为python寻找一模一样的字节数组,我已经将这个Java实现转换为python。

class ByteArray:

@classmethod
def char(cls, args=[]):
    cls.hexArray = "0123456789ABCDEF".encode('utf-16')
    j = 0
    length = (cls.hexArray)

    if j < length:
        v = j & 0xFF
        hexChars = [None, None]
        hexChars[j * 2] = str( cls.hexArray) + str(v)
        hexChars[j * 2 + 1] = str(cls.hexArray) + str(v) + str(0x0F)
        # Use if you want...
        #hexChars.pop()

    return str(hexChars)

array = ByteArray()
print array.char(args=[])