我有一个字节数组充满十六进制数字和打印它的简单方式是相当没有意义的,因为有许多不可打印的元素。我需要的是精确的十六进制形式:3a5f771c


当前回答

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 ) );

其他回答

好的,有很多方法可以做到这一点,但如果你决定使用一个库,我建议在你的项目中看看是否已经在一个库中实现了一些东西,而这个库已经是你项目的一部分,然后再添加一个新的库来做到这一点。例如,如果你还没有

org.apache.commons.codec.binary.Hex

也许你有…

org.apache.xerces.impl.dv.util.HexBin

如果您正在为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=[])

这是一个java.util。类似base64的实现,是不是很漂亮?

import java.util.Arrays;

public class Base16/* a.k.a. Hex */ {
    public static class Encoder{
        private static char[] toLowerHex={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
        private static char[] toUpperHex={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
        private boolean upper;
        public Encoder(boolean upper) {
            this.upper=upper;
        }
        public String encode(byte[] data){
            char[] value=new char[data.length*2];
            char[] toHex=upper?toUpperHex:toLowerHex;
            for(int i=0,j=0; i<data.length; i++){
                int octet=data[i]&0xFF;
                value[j++]=toHex[octet>>4];
                value[j++]=toHex[octet&0xF];
            }
            return new String(value);
        }
        static final Encoder LOWER_CASE=new Encoder(false);
        static final Encoder UPPER_CASE=new Encoder(true);
    }
    public static Encoder getEncoder(){
        return Encoder.LOWER_CASE;
    }
    public static Encoder getUpperEncoder(){
        return Encoder.UPPER_CASE;
    }

    public static class Decoder{
      private static int maxIndex=102;
      private static int[] toIndex;
      static {
        toIndex=new int[maxIndex+1];
        Arrays.fill(toIndex, -1);
        char[] chars={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','a','b','c','d','e','f'};
        for(int i=0; i<chars.length; i++) {
          toIndex[(int)chars[i]]=i;
        }
      }
      public Decoder() {
      }
      public byte[] decode(String str) {
          char[] value=str.toCharArray();
          int start=0;
          if(value.length>2 && value[0]=='0' && (value[1]=='x' || value[1]=='X')) {
            start=2;
          }
          int byteLength=(value.length-start)/2; // ignore trailing odd char if exists
          byte[] data=new byte[byteLength];
          for(int i=start,j=0;i<value.length;i+=2,j++){
              int i1;
              int i2;
              char c1=value[i];
              char c2=value[i+1];
              if(c1>maxIndex || (i1=toIndex[(int)c1])<0 || c2>maxIndex || (i2=toIndex[(int)c2])<0) {
                throw new IllegalArgumentException("Invalid character at "+i);
              }
              data[j]=(byte)((i1<<4)+i2);
          }
          return data;
      }
      static final Decoder IGNORE_CASE=new Decoder();
  }
  public static Decoder getDecoder(){
      return Decoder.IGNORE_CASE;
  }
}

只是迭代所有字节,转换为十六进制字符串使用整数。toString(不幸的是,没有字节。toString(带基数形参)并将它们全部附加到StringBuilder中。

byte[] arr;//set it to your value
StringBuilder sb=new StringBuilder(arr.length*2);//1 byte...2 hex digits
for(int i=0;i<arr.length;i++){
  sb.append(Integer.toString(arr[i],16));
}
String hexValue=sb.toString();

这类似于指针Null的答案,但它使用整数。toString而不是String。格式提高性能。

javax.xml.bind.DatatypeConverter.printHexBinary()方法是用于XML绑定的Java体系结构(JAXB)的一部分,是将字节[]转换为十六进制字符串的方便方法。DatatypeConverter类还包括许多其他有用的数据操作方法。

在Java 8和更早的版本中,JAXB是Java标准库的一部分。它在Java 9中被弃用,在Java 11中被移除,这是将所有Java EE包移动到它们自己的库中的努力的一部分。说来话长。现在,javax.xml.bind还不存在,如果希望使用包含DatatypeConverter的JAXB,则需要从Maven安装JAXB API和JAXB运行时。

使用示例:

byte bytes[] = {(byte)0, (byte)0, (byte)134, (byte)0, (byte)61};
String hex = javax.xml.bind.DatatypeConverter.printHexBinary(bytes);

会导致:

000086003D

这个和这个答案是一样的。