Comment initialiser un tableau d'octets en Java?


Je dois stocker des valeurs constantes (UUID) sous forme de tableau d'octets en java, et je me demande quelle serait la meilleure façon d'initialiser ces tableaux statiques. C'est comme ça que je le fais actuellement, mais je pense qu'il doit y avoir une meilleure façon.

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

Y a-t-il quelque chose que je pourrais utiliser qui pourrait être moins efficace, mais qui aurait l'air plus propre? par exemple:

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

10 answers

En utilisant une fonction convertissant une chaîne hexa en byte[], vous pouvez faire

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

Je vous suggère d'utiliser la fonction définie par Dave L dans Convertir une représentation de chaîne d'un vidage hexadécimal en un tableau d'octets en utilisant Java?

Je l'insère ici pour une lisibilité maximale:

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 vous laissez CDRIVES static et final, la baisse des performances n'est pas pertinente.

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

Les littéraux de chaîne peuvent être échappés pour fournir n'importe quel caractère:

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

Dans Java 6, il existe une méthode faisant exactement ce que vous voulez:

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

Sinon, vous pouvez utiliser Google Goyave:

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

La méthode Goyave est exagérée, lorsque vous utilisez de petits tableaux. Mais Guava a aussi des versions qui peuvent analyser les flux d'entrée. C'est une fonctionnalité intéressante lorsqu'il s'agit de grandes entrées hexadécimales.

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

Vous pouvez utiliser la classe Java UUID pour stocker ces valeurs, au lieu des tableaux d'octets:

UUID

public UUID(long mostSigBits,
            long leastSigBits)

Construit un nouvel UUID en utilisant les données spécifiées. mostSigBits est utilisé pour les 64 bits les plus significatifs de l'UUID et leastSigBits devient les 64 bits les moins significatifs de l'UUID.

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

Une solution sans bibliothèques, longueur dynamique renvoyée, interprétation entière non signée (pas le complément de deux)

    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

Le plus petit type interne, qui au moment de la compilation peut être attribué par des nombres hexadécimaux est char , as

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

Pour avoir un tableau d'octets équivalent, on peut déployer des conversions comme

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

En ce qui concerne un processus propre, vous pouvez utiliser ByteArrayOutputStream objet...

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

//écrivez toutes les valeurs à bObj une par une en utilisant

bObj.write(byte value)

/ / lorsque vous avez terminé, vous pouvez obtenir l'octet [] en utilisant

CDRIVES = bObj.toByteArray();

/ / que vous pouvez répéter le processus similaire pour CMYDOCS et IEFRAME ainsi,

REMARQUE Ce n'est pas une solution efficace si vous avez vraiment un petit tableau.

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

Vous pouvez utiliser cette fonction utilitaire:

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

Contrairement aux variantes de Denys Séguret et stefan.schwetschke, il permet d'insérer des symboles de séparation (espaces, onglets, etc.) dans la chaîne d'entrée, la rendant plus lisible.

Exemple d'utilisation:

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

Mon option préférée dans cette circonstance est d'utiliser org.apache.commons.codec.binary.Hex qui a des Api pour convertir entre Stringy hexadécimal et en binaire. Par exemple:

  1. Hex.decodeHex(char[] data) qui lance un DecoderException s'il y a des caractères non hexadécimaux dans le tableau, ou s'il y a un nombre impair de caractères.

  2. Hex.encodeHex(byte[] data) est la contrepartie de la décoder méthode ci-dessus, et crache le char[].

  3. Hex.encodeHexString(byte[] data) qui convertit arrière à partir d'un byte tableau à une String.

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

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

Et après l'accès convertir en octet.

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