Pregunta ¿Cómo convertir una matriz de bytes a una cadena hexadecimal en Java?


Tengo una matriz de bytes llena de números hexadecimales e imprimirla de la manera fácil es bastante inútil porque hay muchos elementos no imprimibles. Lo que necesito es el hexcode exacto en forma de: 3a5f771c


507
2018-03-11 13:06


origen


Respuestas:


De la discusión aquí, y especialmente esta respuesta, esta es la función que uso actualmente:

private final static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) {
    char[] hexChars = new char[bytes.length * 2];
    for ( int j = 0; j < bytes.length; j++ ) {
        int v = bytes[j] & 0xFF;
        hexChars[j * 2] = hexArray[v >>> 4];
        hexChars[j * 2 + 1] = hexArray[v & 0x0F];
    }
    return new String(hexChars);
}

Mis propios pequeños puntos de referencia (un millón de bytes por mil veces, 256 bytes 10 millones de veces) mostraron que es mucho más rápido que cualquier otra alternativa, la mitad del tiempo en arreglos largos. Comparado con la respuesta de la que lo tomé, al cambiar a operaciones en modo bit, como se sugirió en la discusión, reduje aproximadamente un 20% del tiempo para arreglos largos. (Editar: Cuando digo que es más rápido que las alternativas, me refiero al código alternativo que se ofrece en las discusiones. El rendimiento es equivalente a Commons Codec, que usa un código muy similar).


737
2018-03-24 20:32



los Códec Apache Commons la biblioteca tiene una Maleficio clase para hacer solo este tipo de trabajo.

import org.apache.commons.codec.binary.Hex;

String foo = "I am a string";
byte[] bytes = foo.getBytes();
System.out.println( Hex.encodeHexString( bytes ) );

327
2018-03-11 13:18



Utilizar DatatypeConverter.printHexBinary(). Puedes leer su documentación en http://docs.oracle.com/javase/6/docs/api/javax/xml/bind/DatatypeConverter.html

Por ejemplo:

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

Resultará en:

000086003D

Como puede ver, recuperará la cadena hexadecimal que representa la matriz de bytes con ceros a la izquierda.

Esta respuesta es básicamente la misma que en la pregunta En Java, ¿cómo convierto una matriz de bytes a una cadena de dígitos hexadecimales mientras mantengo los ceros a la izquierda?


289
2018-02-24 15:37



La solución más simple, sin libs externos, sin constantes de dígitos:

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

182
2017-10-22 07:38



Una solución de guayaba, para completar:

import com.google.common.io.BaseEncoding;
...
byte[] bytes = "Hello world".getBytes(StandardCharsets.UTF_8);
final String hex = BaseEncoding.base16().lowerCase().encode(bytes);

Ahora hex es "48656c6c6f20776f726c64".


41
2018-04-07 13:34



Este simple oneliner funciona para mí
String result = new BigInteger(1, inputBytes).toString(16);  
EDITAR - Usar esto eliminará los ceros a la izquierda, pero funcionó para mi caso de uso. Gracias @Voicu por señalarlo


37
2017-11-04 15:30



Usar la clase DataTypeConverterjavax.xml.bind.DataTypeConverter

String hexString = DatatypeConverter.printHexBinary(bytes[] raw);


20
2018-05-12 13:43



Con el menor costo de almacenamiento de la tabla de búsqueda, esta implementación es simple y muy rápida.

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

13
2018-01-29 11:35



Encontré tres formas diferentes aquí: http://www.rgagnon.com/javadetails/java-0596.html

El más elegante, como también señala, creo que es este:

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

12
2018-03-11 13:11



Usaría algo como esto para longitud fija, como hashes:

md5sum = String.format("%032x", new BigInteger(1, md.digest()));

8
2018-01-22 06:00