5

I can do this in Java

final byte[] b = new byte[]{0x01, 0x02, 0x04, 0x08,
                            (byte)0x80, 0x40, 0x20, (byte)0xff,
                            (byte)0xef, 0x40, 0x30, (byte)0xfe,
                            0x3f, (byte)0x90, 0x44, 0x78};

whereas in Python 2.x I can just use

b = '\x01\x02\x04\x08\x80\x40\x20\xff\xef\x40\x30\xfe\x3f\x90\x44\x78'

The Java syntax is a pain and needs (byte) casts to handle values with most significant bit set.

Is there an easier way? (aside from writing a helper class to turn a string like "01020408804020ffef4030fe3f904478" into a byte[])

Jason S
  • 184,598
  • 164
  • 608
  • 970
  • You could use `BigInteger` to avoid having to write the helper class yourself. – resueman May 16 '16 at 16:50
  • 1
    *"aside from writing a helper class..."* I suspect not. – T.J. Crowder May 16 '16 at 16:52
  • 1
    @malbarbo -- Not a duplicate of that question, which just wants to know how to fix a problem caused by lack of casts. I *know* that the default way to create a byte array literal in Java requires casts, I want to know if there is a way to express byte arrays more compactly. – Jason S May 16 '16 at 16:53
  • This question pre-supposes the answer to the above-linked question; not a dupe in my opinion. Unfortunately, I think the answer to OP's question (is there a better way) is 'no'. – Gus May 16 '16 at 16:56

1 Answers1

3

Pick your poison. All the alternatives are painful in one way or another.
It is lamentable that Java's byte type is signed instead of unsigned.

  1. Hexadecimal byte constants with casting. For uniformness, you should just cast every element. This is okay for very short lists.

    byte[] b = {(byte)0x00, (byte)0x7F, (byte)0x80, (byte)0xFF};
    
  2. Signed decimal byte constants, to avoid casting. Very few tools can read or write this format easily though. Probably not useful in practice.

    byte[] b = {0, 127, -128, -1};
    
  3. Int-to-byte conversion via a helper function. It does look neat and tidy, and is helpful for medium amounts of data.

    byte[] b = toBytes(new int[]{0x00, 0x7F, 0x80, 0xFF});
    
    static byte[] toBytes(int[] x) {
        byte[] y = new byte[x.length];
        for (int i = 0; i < x.length; i++)
            y[i] = (byte)x[i];
        return y;
    }
    
  4. String-to-byte conversion. Now you can use just 2 characters per byte (no commas or 0x), plus a constant amount of overhead.

    byte[] b = hexToBytes("007F80FF");
    
    static byte[] hexToBytes(String s) {
        byte[] b = new byte[s.length() / 2];
        for (int i = 0; i < b.length; i++)
            b[i] = (byte)Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16);
        return b;
    }
    
  5. Base64-encoded string. This is even more compact than #4, but requires work to encode. Decoding is easy using java.util.Base64 (Java SE 8+). I have one actual example where I stored a Base64 binary blob in my Java source code.

Nayuki
  • 17,911
  • 6
  • 53
  • 80