web-dev-qa-db-ja.com

Javaでバイト配列を初期化する方法

私はいくつかの定数値(UUID)をバイト配列形式でJavaに格納しなければなりません、そしてそれらの静的配列を初期化するための最良の方法は何だろうと思います。これが私の現在のやり方ですが、もっと良い方法があるはずです。

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

それほど効率的ではないかもしれませんが、もっときれいに見えるものを使用することができますか?例えば:

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

16進数文字列をbyte[]に変換する関数を使うと、

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

Dave Lで定義されている関数をJavaを使って16進ダンプの文字列表現をバイト配列に変換することをお勧めします。

読みやすくするためにここに挿入します。

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

CDRIVESをstaticfinalとすると、パフォーマンスの低下は無関係です。

103
Denys Séguret
byte[] myvar = "Any String you want".getBytes();

文字列リテラルをエスケープして任意の文字を指定できます。

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

Java 6には、あなたが望むことを正確に行う方法があります。

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

あるいは、 Google Guava を使用することもできます。

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

小さな配列を使用している場合、Guavaの方法はやり過ぎです。しかし、Guavaには入力ストリームを解析できるバージョンもあります。これは大きな16進数入力を扱うときのいい機能です。

32

これらの値を格納するために、バイト配列の代わりにJava UUIDクラスを使用できます。

UUID

public UUID(long mostSigBits,
            long leastSigBits)

指定されたデータを使って新しいUUIDを作成します。 mostSigBitsはUUIDの最上位64ビットに使用され、leastSigBitsはUUIDの最下位64ビットになります。

7
Jon

クリーンプロセスに関しては、ByteArrayOutputStreamオブジェクトを使用できます。

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

//すべての値を1つずつbObjに書き込む

bObj.write(byte value)

//終了したら、次のようにしてbyte []を取得できます。

CDRIVES = bObj.toByteArray();

// CMYDOCSとIEFRAMEについても同様のプロセスを繰り返すことができます

NOTE本当に小さい配列がある場合、これは効率的な解決策ではありません。

2
Amit

ライブラリのない解決法、動的長が返される、符号なし整数の解釈(2の補数ではない)

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

このような状況では、Stringy hexとbinaryの間の変換に役立つAPIを持つorg.Apache.commons.codec.binary.Hexを使用することをお勧めします。例えば:

  1. 配列内に非16進文字がある場合、または奇数の文字がある場合は、Hex.decodeHex(char[] data)DecoderExceptionをスローします。

  2. Hex.encodeHex(byte[] data)は上記のdecodeメソッドの対応物であり、char[]を吐き出します。

  3. byte配列からString配列に逆変換するHex.encodeHexString(byte[] data)

使用法:Hex.decodeHex("dd645a2564cbe648c8336d2be5eafaa6".toCharArray())

1
rbrtl

このユーティリティ機能を使用することができます。

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

DenysSéguretやstefan.schwetschkeの変種とは異なり、入力文字列に区切り記号(スペース、タブなど)を挿入して読みやすくします。

使用例

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");
0
John McClane