我有一个字节数组充满十六进制数字和打印它的简单方式是相当没有意义的,因为有许多不可打印的元素。我需要的是精确的十六进制形式:3a5f771c
当前回答
public static String toHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder();
if (bytes != null)
for (byte b:bytes) {
final String hexString = Integer.toHexString(b & 0xff);
if(hexString.length()==1)
sb.append('0');
sb.append(hexString);//.append(' ');
}
return sb.toString();//.toUpperCase();
}
使用DatatypeConverter:
public String toHexString(byte... bytes) {
return Optional.ofNullable(bytes)
.filter(bs->bs.length>0)
.map(DatatypeConverter::printHexBinary)
.map(str->IntStream.range(0, str.length())
.filter(i->(i%2)==0) // take every second index
.mapToObj(i->"0x" + str.substring(i, i+2))
.collect(Collectors.joining(" ")))
.orElse("");
}
其他回答
Java 17最终包含HexFormat类,所以你可以简单地做:
HexFormat.of().formatHex(bytes);
它支持配置为小写/大写,分隔符,前缀,后缀等。
@maybewecouldstealavan提出的解决方案的一个小变种,它让你在输出十六进制字符串中可视化地捆绑N个字节:
final static char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
final static char BUNDLE_SEP = ' ';
public static String bytesToHexString(byte[] bytes, int bundleSize /*[bytes]*/]) {
char[] hexChars = new char[(bytes.length * 2) + (bytes.length / bundleSize)];
for (int j = 0, k = 1; j < bytes.length; j++, k++) {
int v = bytes[j] & 0xFF;
int start = (j * 2) + j/bundleSize;
hexChars[start] = HEX_ARRAY[v >>> 4];
hexChars[start + 1] = HEX_ARRAY[v & 0x0F];
if ((k % bundleSize) == 0) {
hexChars[start + 2] = BUNDLE_SEP;
}
}
return new String(hexChars).trim();
}
那就是:
bytesToHexString("..DOOM..".toCharArray().getBytes(), 2);
2E2E 444F 4F4D 2E2E
bytesToHexString("..DOOM..".toCharArray().getBytes(), 4);
2E2E444F 4F4D2E2E
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);
}
我发现了三种不同的方法: 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();
}
对于固定长度,我会使用这样的东西,比如哈希值:
md5sum = String.format("%032x", new BigInteger(1, md.digest()));
推荐文章
- 如何在java中格式化持续时间?(如格式H:MM:SS)
- urlencoder .encode(字符串)已弃用,我应该使用什么代替?
- javax.transaction.Transactional vs . org.springframework.transaction.annotation.Transactional
- Java 8接口方法中不允许“同步”的原因是什么?
- 如何找到Java堆大小和内存使用(Linux)?
- 使用Enum实现单例(Java)
- RabbitMQ与通道和连接之间的关系
- buildSessionFactory()配置方法在Hibernate中已弃用?
- Spring MVC -如何获得所有的请求参数在一个地图在Spring控制器?
- 如何在Java中按两个字段排序?
- 文件之间的差异。路径中的分隔符和斜杠
- 在方法参数中使用NotNull注释
- Spring MVC中处理可选参数的@RequestParam
- Tomcat:如何查找正在运行的Tomcat版本?
- “java”、“javaw”和“javaws”之间有什么区别?