Hoe initialiseer ik een bytearray in Java?

Ik moet een aantal constante waarden (UUID’s) in byte-arrayvorm in java opslaan en ik vraag me af wat de beste manier is om die statische arrays te initialiseren. Dit is hoe ik het momenteel doe, maar ik heb het gevoel dat er een betere manier moet zijn.

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

Is er iets dat ik zou kunnen gebruiken dat misschien minder efficiënt is, maar er wel schoner uitziet?
bijvoorbeeld:

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

Antwoord 1, autoriteit 100%

Als u een functie gebruikt die een hexa-tekenreeks converteert naar byte[], kunt u

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

Ik raad je aan de functie te gebruiken die is gedefinieerd door Dave L in Een string-representatie van een hex-dump converteren naar een byte-array met Java?

Ik voeg het hier in voor maximale leesbaarheid:

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

Als je CDRIVES staticen finallaat, is de prestatiedaling niet relevant.


Antwoord 2, autoriteit 74%

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

Letterlijke tekenreeksen kunnen worden geëscaped om elk teken op te geven:

byte[] CDRIVES = "\u00e0\u004f\u00d0\u0020\u00ea\u003a\u0069\u0010\u00a2\u00d8\u0008\u0000\u002b\u0030\u0030\u009d".getBytes();

Antwoord 3, autoriteit 28%

In Java 6 is er een methode die precies doet wat u wilt:

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

U kunt ook Google Guavagebruiken:

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

De Guava-methode is overkill als je kleine arrays gebruikt. Maar Guava heeft ook versies die invoerstromen kunnen ontleden. Dit is een leuke functie als je te maken hebt met grote hexadecimale invoer.


Antwoord 4, autoriteit 6%

U kunt de Java UUID-klasse gebruiken om deze waarden op te slaan, in plaats van bytearrays:

UUID
public UUID(long mostSigBits,
            long leastSigBits)

Construeert een nieuwe UUID met behulp van de opgegeven gegevens. mostSigBits wordt gebruikt voor de meest significante 64 bits van de UUID en leastSigBits wordt de minst significante 64 bits van de UUID.


Antwoord 5, autoriteit 3%

Het kleinste interne type, dat tijdens het compileren kan worden toegewezen door hexadecimale getallen is char, as

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

Om een gelijkwaardige bytearray te hebben, zou men conversies kunnen implementeren als

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

Antwoord 6, autoriteit 2%

Een oplossing zonder bibliotheken, dynamische lengte geretourneerd, niet-ondertekende integer-interpretatie (geen twee-complement)

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

Antwoord 7, autoriteit 2%

U kunt deze hulpprogramma-functie gebruiken:

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

In tegenstelling tot varianten van Denys Séguret en stefan.schwetschke, is het mogelijk om scheidingstekens (spaties, tabs, enz.) in de invoerreeks in te voegen, waardoor deze beter leesbaar wordt.

Voorbeeld van gebruik:

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

Antwoord 8, autoriteit 2%

Voor een schoon proces kun je ByteArrayOutputStream-object…

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

//schrijf alle waarden één voor één naar bObj met

bObj.write(byte value)

// als je klaar bent, kun je de byte[] krijgen met

CDRIVES = bObj.toByteArray();

//dan kun je hetzelfde proces herhalen voor CMYDOCS en IEFRAME,

OPMERKINGDit is geen efficiënte oplossing als je echt een kleine array hebt.


Antwoord 9, autoriteit 2%

Mijn voorkeursoptie in dit geval is om org.apache.commons.codec.binary.Hexte gebruiken die handige API’s heeft voor het converteren tussen Stringy hex en binair. Bijvoorbeeld:

  1. Hex.decodeHex(char[] data)die een DecoderExceptiongenereert als er niet-hex-tekens in de array zijn, of als er een oneven aantal tekens.

  2. Hex.encodeHex(byte[] data)is de tegenhanger van de bovenstaande decoderingsmethode en spuugt de char[]uit.

  3. Hex.encodeHexString(byte[] data)die terug converteert van een bytearray naar een String.

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


Antwoord 10

Je kunt het springkasteelpakket gebruiken,

Maven importeren,

 <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15on</artifactId>
    </dependency>

Java-code,

byte[] CDRIVES = Hex.decode("e04fd020ea3a6910a2d808002b30309d");

Antwoord 11

private static final int[] CDRIVES = new int[] {0xe0, 0xf4, ...};

en na toegang converteren naar byte.

Other episodes