¿Cómo inicializo una matriz de bytes en Java?

Tengo que almacenar algunos valores constantes (UUID) en forma de matriz de bytes en java, y me pregunto cuál sería la mejor manera de inicializar esas matrices estáticas. Así es como lo estoy haciendo actualmente, pero siento que debe haber una mejor manera.

private static final byte[] CDRIVES = new byte[] { (byte)0xe0, 0x4f, (byte)0xd0, 0x20, (byte)0xea, 0x3a, 0x69, 0x10, (byte)0xa2, (byte)0xd8, 0x08, 0x00, 0x2b, 0x30, 0x30, (byte)0x9d }; private static final byte[] CMYDOCS = new byte[] { (byte)0xba, (byte)0x8a, 0x0d, 0x45, 0x25, (byte)0xad, (byte)0xd0, 0x11, (byte)0x98, (byte)0xa8, 0x08, 0x00, 0x36, 0x1b, 0x11, 0x03 }; private static final byte[] IEFRAME = new byte[] { (byte)0x80, 0x53, 0x1c, (byte)0x87, (byte)0xa0, 0x42, 0x69, 0x10, (byte)0xa2, (byte)0xea, 0x08, 0x00, 0x2b, 0x30, 0x30, (byte)0x9d }; ... and so on 

¿Hay algo que pueda usar que sea menos eficiente, pero que se vea más limpio? por ejemplo:

 private static final byte[] CDRIVES = new byte[] { "0xe04fd020ea3a6910a2d808002b30309d" }; 

Usando una función que convierte una cadena hexadecimal en byte[] , podrías hacer

 byte[] CDRIVES = hexStringToByteArray("e04fd020ea3a6910a2d808002b30309d"); 

Te sugiero que uses la función definida por Dave L en Convertir una representación de cadena de un volcado hexadecimal a una matriz de bytes usando Java?

Lo inserto aquí para una máxima legibilidad:

 public static byte[] hexStringToByteArray(String s) { int len = s.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16)); } return data; } 

Si deja CDRIVES static y final , la caída del rendimiento es irrelevante.

 byte[] myvar = "Any String you want".getBytes(); 

En Java 6, hay un método que hace exactamente lo que quiere:

 private static final byte[] CDRIVES = javax.xml.bind.DatatypeConverter.parseHexBinary("e04fd020ea3a6910a2d808002b30309d") 

Alternativamente, podrías usar Google Guava :

 import com.google.common.io.BaseEncoding; private static final byte[] CDRIVES = BaseEncoding.base16().lowerCase().decode("E04FD020ea3a6910a2d808002b30309d".toLowerCase()); 

El método de la guayaba es exagerado, cuando se utilizan matrices pequeñas. Pero Guava también tiene versiones que pueden analizar flujos de entrada. Esta es una buena característica cuando se trata de grandes entradas hexadecimales.

Puede usar la clase Java UUID para almacenar estos valores, en lugar de matrices de bytes:

 UUID public UUID(long mostSigBits, long leastSigBits) 

Construye un nuevo UUID utilizando los datos especificados. mostSigBits se usa para los 64 bits más significativos del UUID y leastSigBits se convierte en los 64 bits menos significativos del UUID.

En lo que respecta a un proceso de limpieza, puede usar el objeto ByteArrayOutputStream

 ByteArrayOutputStream bObj = new ByteArrayOutputStream(); bObj.reset(); 

// escribe todos los valores en bObj uno por uno usando

 bObj.write(byte value) 

// cuando hayas terminado puedes obtener el byte [] usando

 CDRIVES = bObj.toByteArray(); 

// de lo que puede repetir el proceso similar para CMYDOCS y IEFRAME también,

NOTA: esta no es una solución eficiente si realmente tiene una matriz pequeña.

Mi opción preferida en esta circunstancia es usar org.apache.commons.codec.binary.Hex que tiene API útiles para convertir entre String y hexadecimal y binario. Por ejemplo:

  1. Hex.decodeHex(char[] data) que arroja una DecoderException si hay caracteres no hexadecimales en la matriz, o si hay un número impar de caracteres.

  2. Hex.encodeHex(byte[] data) es la contraparte del método de deencoding anterior, y escupe el char[] .

  3. Hex.encodeHexString(byte[] data) que convierte de una matriz de byte a una String .

Uso: Hex.decodeHex("dd645a2564cbe648c8336d2be5eafaa6".toCharArray())

Una solución sin bibliotecas, longitud dinámica devuelta, interpretación de entero sin signo (no complemento de dos)

  public static byte[] numToBytes(int num){ if(num == 0){ return new byte[]{}; }else if(num < 256){ return new byte[]{ (byte)(num) }; }else if(num < 65536){ return new byte[]{ (byte)(num >>> 8),(byte)num }; }else if(num < 16777216){ return new byte[]{ (byte)(num >>> 16),(byte)(num >>> 8),(byte)num }; }else{ // up to 2,147,483,647 return new byte[]{ (byte)(num >>> 24),(byte)(num >>> 16),(byte)(num >>> 8),(byte)num }; } } 
 private static final int[] CDRIVES = new int[] {0xe0, 0xf4, ...}; 

y después del acceso convertir a byte.