我有一个字节数组充满十六进制数字和打印它的简单方式是相当没有意义的,因为有许多不可打印的元素。我需要的是精确的十六进制形式:3a5f771c
当前回答
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();
}
其他回答
为了完整起见,一个番石榴解决方案:
import com.google.common.io.BaseEncoding;
...
byte[] bytes = "Hello world".getBytes(StandardCharsets.UTF_8);
final String hex = BaseEncoding.base16().lowerCase().encode(bytes);
现在十六进制是“48656c6c6f20776f726c64”。
在这一页上找不到任何解决方案吗
使用循环 使用javax.xml.bind.DatatypeConverter,它编译良好,但经常在运行时抛出java.lang.NoClassDefFoundError。
这里有一个解决方案,它没有上面的缺陷(不保证我的没有其他缺陷)
import java.math.BigInteger;
import static java.lang.System.out;
public final class App2 {
// | proposed solution.
public static String encode(byte[] bytes) {
final int length = bytes.length;
// | BigInteger constructor throws if it is given an empty array.
if (length == 0) {
return "00";
}
final int evenLength = (int)(2 * Math.ceil(length / 2.0));
final String format = "%0" + evenLength + "x";
final String result = String.format (format, new BigInteger(bytes));
return result;
}
public static void main(String[] args) throws Exception {
// 00
out.println(encode(new byte[] {}));
// 01
out.println(encode(new byte[] {1}));
//203040
out.println(encode(new byte[] {0x20, 0x30, 0x40}));
// 416c6c20796f75722062617365206172652062656c6f6e6720746f2075732e
out.println(encode("All your base are belong to us.".getBytes()));
}
}
我不能在62个操作码下得到这个,但如果你可以在第一个字节小于0x10的情况下没有0填充,那么下面的解决方案只使用23个操作码。真正展示了“容易实现自己”的解决方案,如“如果字符串长度为奇数,则填充为零”,如果本机实现还不可用(或者在本例中,如果BigInteger在toString中有一个以零作为前缀的选项),则可能会非常昂贵。
public static String encode(byte[] bytes) {
final int length = bytes.length;
// | BigInteger constructor throws if it is given an empty array.
if (length == 0) {
return "00";
}
return new BigInteger(bytes).toString(16);
}
最简单的解决方案,没有外部库,没有数字常量:
public static String byteArrayToHex(byte[] a) {
StringBuilder sb = new StringBuilder(a.length * 2);
for(byte b: a)
sb.append(String.format("%02x", b));
return sb.toString();
}
HexFormat是在Java 17中加入的:
String hex = HexFormat.of().formatHex(array);
我们不需要使用任何外部库,也不需要基于循环和常量编写代码。 这样就够了:
byte[] theValue = .....
String hexaString = new BigInteger(1, theValue).toString(16);
推荐文章
- “比较法违反其总合同!”
- 从Java项目生成UML类图
- 正确地从一个<Integer>的列表中移除一个整数
- Java开关语句:需要常量表达式,但它是常量
- Java的assertEquals方法可靠吗?
- 如何在Java中获得系统变量值?
- 比较Java中2个XML文档的最佳方法
- Java SE 8有对或元组吗?
- Java 8流的.min()和.max():为什么编译?
- 生成1和10之间的随机数Java
- 我如何从资产文件夹解析一个本地JSON文件到一个ListView?
- 将枚举转换为集合/列表
- 在Java中创建对象数组
- Java中字符串的字节数
- IntelliJ IDEA with Junit 4.7”!!JUnit 3.8或更高版本: