我有一个字节数组充满十六进制数字和打印它的简单方式是相当没有意义的,因为有许多不可打印的元素。我需要的是精确的十六进制形式:3a5f771c
当前回答
我的解决方案是基于maybeWeCouldStealAVan的解决方案,但不依赖于任何额外分配的查找表。它不使用任何“int-to-char”类型强制转换(实际上,Character.forDigit()做到了这一点,执行一些比较来检查数字的真实情况),因此可能会稍慢一些。请随意在任何你想用的地方使用。欢呼。
public static String bytesToHex(final byte[] bytes)
{
final int numBytes = bytes.length;
final char[] container = new char[numBytes * 2];
for (int i = 0; i < numBytes; i++)
{
final int b = bytes[i] & 0xFF;
container[i * 2] = Character.forDigit(b >>> 4, 0x10);
container[i * 2 + 1] = Character.forDigit(b & 0xF, 0x10);
}
return new String(container);
}
其他回答
我通常使用以下方法进行debuf语句,但我不知道这是否是最好的方法
private static String digits = "0123456789abcdef";
public static String toHex(byte[] data){
StringBuffer buf = new StringBuffer();
for (int i = 0; i != data.length; i++)
{
int v = data[i] & 0xff;
buf.append(digits.charAt(v >> 4));
buf.append(digits.charAt(v & 0xf));
}
return buf.toString();
}
Apache Commons Codec库有一个Hex类用于完成这种类型的工作。
import org.apache.commons.codec.binary.Hex;
String foo = "I am a string";
byte[] bytes = foo.getBytes();
System.out.println( Hex.encodeHexString( bytes ) );
如果您正在为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=[])
我发现了三种不同的方法: http://www.rgagnon.com/javadetails/java-0596.html
他还提到,我认为最优雅的一个是:
static final String HEXES = "0123456789ABCDEF";
public static String getHex( byte [] raw ) {
if ( raw == null ) {
return null;
}
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();
}
在存储查找表的很小代价下,这个实现非常简单和快速。
private static final char[] BYTE2HEX=(
"000102030405060708090A0B0C0D0E0F"+
"101112131415161718191A1B1C1D1E1F"+
"202122232425262728292A2B2C2D2E2F"+
"303132333435363738393A3B3C3D3E3F"+
"404142434445464748494A4B4C4D4E4F"+
"505152535455565758595A5B5C5D5E5F"+
"606162636465666768696A6B6C6D6E6F"+
"707172737475767778797A7B7C7D7E7F"+
"808182838485868788898A8B8C8D8E8F"+
"909192939495969798999A9B9C9D9E9F"+
"A0A1A2A3A4A5A6A7A8A9AAABACADAEAF"+
"B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF"+
"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF"+
"D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF"+
"E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF"+
"F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF").toCharArray();
;
public static String getHexString(byte[] bytes) {
final int len=bytes.length;
final char[] chars=new char[len<<1];
int hexIndex;
int idx=0;
int ofs=0;
while (ofs<len) {
hexIndex=(bytes[ofs++] & 0xFF)<<1;
chars[idx++]=BYTE2HEX[hexIndex++];
chars[idx++]=BYTE2HEX[hexIndex];
}
return new String(chars);
}
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap