我有一个字节数组。 我希望将该数组的每个字节String转换为相应的十六进制值。
Java中是否有将字节数组转换为十六进制的函数?
我有一个字节数组。 我希望将该数组的每个字节String转换为相应的十六进制值。
Java中是否有将字节数组转换为十六进制的函数?
当前回答
下面是一个将字节转换为十六进制的简单函数
private static String convertToHex(byte[] data) {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < data.length; i++) {
int halfbyte = (data[i] >>> 4) & 0x0F;
int two_halfs = 0;
do {
if ((0 <= halfbyte) && (halfbyte <= 9))
buf.append((char) ('0' + halfbyte));
else
buf.append((char) ('a' + (halfbyte - 10)));
halfbyte = data[i] & 0x0F;
} while(two_halfs++ < 1);
}
return buf.toString();
}
其他回答
BigInteger n = new BigInteger(byteArray);
String hexa = n.toString(16);
我所发现的最快的方法是:
private static final String HEXES = "0123456789ABCDEF";
static String getHex(byte[] raw) {
final StringBuilder hex = new StringBuilder(2 * raw.length);
for (final byte b : raw) {
hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt((b & 0x0F)));
}
return hex.toString();
}
它比String.format快50倍。如果你想测试它:
public class MyTest{
private static final String HEXES = "0123456789ABCDEF";
@Test
public void test_get_hex() {
byte[] raw = {
(byte) 0xd0, (byte) 0x0b, (byte) 0x01, (byte) 0x2a, (byte) 0x63,
(byte) 0x78, (byte) 0x01, (byte) 0x2e, (byte) 0xe3, (byte) 0x6c,
(byte) 0xd2, (byte) 0xb0, (byte) 0x78, (byte) 0x51, (byte) 0x73,
(byte) 0x34, (byte) 0xaf, (byte) 0xbb, (byte) 0xa0, (byte) 0x9f,
(byte) 0xc3, (byte) 0xa9, (byte) 0x00, (byte) 0x1e, (byte) 0xd5,
(byte) 0x4b, (byte) 0x89, (byte) 0xa3, (byte) 0x45, (byte) 0x35,
(byte) 0xd6, (byte) 0x10,
};
int N = 77777;
long t;
{
t = System.currentTimeMillis();
for (int i = 0; i < N; i++) {
final StringBuilder hex = new StringBuilder(2 * raw.length);
for (final byte b : raw) {
hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt((b & 0x0F)));
}
hex.toString();
}
System.out.println(System.currentTimeMillis() - t); // 50
}
{
t = System.currentTimeMillis();
for (int i = 0; i < N; i++) {
StringBuilder hex = new StringBuilder(2 * raw.length);
for (byte b : raw) {
hex.append(String.format("%02X", b));
}
hex.toString();
}
System.out.println(System.currentTimeMillis() - t); // 2535
}
}
}
编辑:刚刚发现一些东西只是稍微快一点,保持在一行,但与JRE 9不兼容。使用风险自负
import javax.xml.bind.DatatypeConverter;
DatatypeConverter.printHexBinary(raw);
Java 17:引入Java .util. hexformat
Java 17提供了一个实用程序,可以将字节数组和数字转换为对应的十六进制数。假设我们有一个“Hello World”的MD5摘要作为一个字节数组:
var md5 = MessageDigest.getInstance("md5");
md5.update("Hello world".getBytes(UTF_8));
var digest = md5.digest();
现在我们可以使用HexFormat.of().formatHex(byte[])方法将给定的byte[]转换为它的十六进制形式:
jshell> HexFormat.of().formatHex(digest)
$7 ==> "3e25960a79dbc69b674cd4ec67a72c62"
withUpperCase()方法返回前面输出的大写版本:
jshell> HexFormat.of().withUpperCase().formatHex(digest)
$8 ==> "3E25960A79DBC69B674CD4EC67A72C62"
试试这个方法:
byte bv = 10;
String hexString = Integer.toHexString(bv);
处理数组(如果我没理解错的话):
byte[] bytes = {9, 10, 11, 15, 16};
StringBuffer result = new StringBuffer();
for (byte b : bytes) {
result.append(String.format("%02X ", b));
result.append(" "); // delimiter
}
return result.toString();
正如polygeneluants所提到的,String.format()是与Integer.toHexString()相比的正确答案(因为它以正确的方式处理负数)。
如果您乐于使用外部库,则org.apache.commons.codec.binary.Hex类有一个encodeHex方法,该方法接受一个字节[]并返回一个char[]。这个方法比format选项快得多,并且封装了转换的细节。还附带了一个decodeHex方法,用于相反的转换。