Come inizializzare un array di byte in Java?


Devo memorizzare alcuni valori costanti (UUID) in forma di array di byte in java, e mi chiedo quale sia il modo migliore per inizializzare quegli array statici. Questo è il modo in cui lo sto facendo, ma sento che ci deve essere un modo migliore.

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

C'è qualcosa che potrei usare che potrebbe essere meno efficiente, ma sembrerebbe più pulito? ad esempio:

private static final byte[] CDRIVES =
    new byte[] { "0xe04fd020ea3a6910a2d808002b30309d" };
Author: dfickling, 2012-06-26

10 answers

Usando una funzione che converte una stringa hexa in byte[], potresti fare

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

Ti suggerirei di usare la funzione definita da Dave L in Convertire una rappresentazione di stringa di un dump esadecimale in un array di byte usando Java?

Lo inserisco qui per la massima leggibilità:

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

Se si lascia CDRIVE static e final, il calo delle prestazioni è irrilevante.

 121
Author: Denys Séguret, 2017-05-23 12:10:26
byte[] myvar = "Any String you want".getBytes();

I letterali di stringa possono essere sfuggiti per fornire qualsiasi carattere:

byte[] CDRIVES = "\u00e0\u004f\u00d0\u0020\u00ea\u003a\u0069\u0010\u00a2\u00d8\u0008\u0000\u002b\u0030\u0030\u009d".getBytes();
 85
Author: petmez, 2019-01-30 11:50:12

In Java 6, c'è un metodo che fa esattamente quello che vuoi:

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

In alternativa puoi usare Google Guava:

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

Il metodo Guava è eccessivo, quando si utilizzano piccoli array. Ma Guava ha anche versioni che possono analizzare i flussi di input. Questa è una bella caratteristica quando si ha a che fare con grandi ingressi esadecimali.

 35
Author: stefan.schwetschke, 2016-08-08 15:49:45

È possibile utilizzare la classe Java UUID per memorizzare questi valori, invece di array di byte:

UUID

public UUID(long mostSigBits,
            long leastSigBits)

Costruisce un nuovo UUID utilizzando i dati specificati. mostSigBits viene utilizzato per i 64 bit più significativi dell'UUID e leastSigBits diventa il 64 bit meno significativo dell'UUID.

 7
Author: Jon, 2012-06-26 13:36:51

Una soluzione senza librerie, lunghezza dinamica restituita, interpretazione intera senza segno (non complemento di due)

    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 };
    }
}
 3
Author: ZMitton, 2017-11-10 20:49:30

Il tipo interno più piccolo, che in fase di compilazione può essere assegnato da numeri esadecimali è char, come

private static final char[] CDRIVES_char = new char[] {0xe0, 0xf4, ...};

Per avere un array di byte equivalente è possibile distribuire le conversioni come

public static byte[] charToByteArray(char[] x)
{
    final byte[] res = new byte[x.length];
    for (int i = 0; i < x.length; i++)
    {
        res[i] = (byte) x[i];
    }
    return res;
}

public static byte[][] charToByteArray(char[][] x)
{
    final byte[][] res = new byte[x.length][];
    for (int i = 0; i < x.length; i++)
    {
        res[i] = charToByteArray(x[i]);
    }
    return res;
}
 3
Author: Sam Ginrich, 2020-04-19 11:57:58

Per quanto riguarda un processo pulito è possibile utilizzare ByteArrayOutputStream oggetto...

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

//scrivi tutti i valori su bObj uno per uno usando

bObj.write(byte value)

/ / al termine è possibile ottenere il byte [] utilizzando

CDRIVES = bObj.toByteArray();

/ / di quanto tu possa ripetere il processo simile anche per CMYDOCS e IEFRAME,

NOTA Questa non è una soluzione efficiente se hai davvero un array piccolo.

 2
Author: Amit, 2015-12-18 05:32:13

È possibile utilizzare questa funzione di utilità:

public static byte[] fromHexString(String src) {
    byte[] biBytes = new BigInteger("10" + src.replaceAll("\\s", ""), 16).toByteArray();
    return Arrays.copyOfRange(biBytes, 1, biBytes.length);
}

A differenza delle varianti di Denys Séguret e stefan.schwetschke, permette l'inserimento di simboli di separazione (spazi, tabulazioni, eccetera.) nella stringa di input, rendendola più leggibile.

Esempio di utilizzo:

private static final byte[] CDRIVES
    = fromHexString("e0 4f d0 20 ea 3a 69 10 a2 d8 08 00 2b 30 30 9d");
private static final byte[] CMYDOCS
    = fromHexString("BA8A0D4525ADD01198A80800361B1103");
private static final byte[] IEFRAME
    = fromHexString("80531c87 a0426910 a2ea0800 2b30309d");
 2
Author: John McClane, 2018-11-25 01:11:32

La mia opzione preferita in questa circostanza è usare org.apache.commons.codec.binary.Hexche ha API utili per la conversione tra String y hex e binario. Ad esempio:

  1. Hex.decodeHex(char[] data) che genera un DecoderException se ci sono caratteri non esadecimali nell'array o se ci sono un numero dispari di caratteri.

  2. Hex.encodeHex(byte[] data) è la controparte del metodo di decodifica di cui sopra, e sputa fuori il char[].

  3. Hex.encodeHexString(byte[] data) che converte da un array byte a un String.

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

 1
Author: rbrtl, 2016-10-13 10:19:34
private static final int[] CDRIVES = new int[] {0xe0, 0xf4, ...};

E dopo l'accesso convertire in byte.

 -2
Author: Frankie, 2017-09-05 11:08:21