我有一个字节数组。 我希望将该数组的每个字节String转换为相应的十六进制值。
Java中是否有将字节数组转换为十六进制的函数?
我有一个字节数组。 我希望将该数组的每个字节String转换为相应的十六进制值。
Java中是否有将字节数组转换为十六进制的函数?
当前回答
BigInteger n = new BigInteger(byteArray);
String hexa = n.toString(16);
其他回答
试试这个方法:
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()相比的正确答案(因为它以正确的方式处理负数)。
Use
Integer.toHexString((int)b);
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扩大原语转换
只是添加我的两分,因为我看到许多答案使用字符数组和/或使用StringBuilder实例,并声称是快速或更快。
由于我使用ASCII表组织有一个不同的想法,代码点48-57为0-9,代码点65-70为a-f,代码点97-102为a-f,我想测试哪个想法是最快的。
因为我已经好几年没有做过类似的事情了,所以我要做一个广泛的拍摄。我在不同大小的数组中使用了10亿字节(1M, 1K, 10),因此每个数组有1000倍1M字节,每个数组有1M倍1000字节,每个数组有100M倍10字节。
结果是1-F中的char数组胜出。使用char数组而不是StringBuilder作为输出也很容易(对象更少,不需要测试容量,在增长时不需要新数组或复制)。此外,当使用foreach (for(var b: bytes))循环时,你似乎会得到一个小的惩罚。
使用我的想法的版本大约是。每个数组1M字节时慢15%,每个数组1000字节时慢21%,每个数组10字节时慢18%。StringBuilder版本分别慢了210%、380%和310%。
这很糟糕,但也不是那么出乎意料,因为在第一级缓存中查找小数组胜过if和add... .(一个缓存访问+偏移量计算vs.一个if,一个跳转,一个add ->不确定跳转thou)。
我的版本:
public static String bytesToHex(byte [] bytes) {
char [] result = new char [bytes.length * 2];
for(int index = 0; index < bytes.length; index++) {
int v = bytes[index];
int upper = (v >>> 4) & 0xF;
result[index * 2] = (char)(upper + (upper < 10 ? 48 : 65 - 10));
int lower = v & 0xF;
result[index * 2 + 1] = (char)(lower + (lower < 10 ? 48 : 65 - 10));
}
return new String(result);
}
PS:是的,我做了多次测试,每次都做了最好的测试,做了热身,也做了100亿字符的测试,以确保相同的图片... .
如果你使用奇妙仙子,那么有:
package com.google.crypto.tink.subtle;
public final class Hex {
public static String encode(final byte[] bytes) { ... }
public static byte[] decode(String hex) { ... }
}
所以像这样的东西应该是有用的:
import com.google.crypto.tink.subtle.Hex;
byte[] bytes = {-1, 0, 1, 2, 3 };
String enc = Hex.encode(bytes);
byte[] dec = Hex.decode(enc)