I have to store some constant values (UUIDs) in byte array form in java, and I'm wondering what the best way to initialize those static arrays would be. This is how I'm currently doing it, but I feel like there must be a better way.
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 there anything I could use that may be less efficient, but would look cleaner? for example:
private static final byte[] CDRIVES = new byte[] < "0xe04fd020ea3a6910a2d808002b30309d" >;
asked Jun 26, 2012 at 13:33
2,645 2 2 gold badges 17 17 silver badges 13 13 bronze badges
Since they're declared as static final , this might already be the most proper way; the accepted answer completely ignores these keywords and would not even work with them.
Commented Jan 17, 2021 at 19:04You can use an utility function to convert from the familiar hexa string to a byte[] . When used to define a final static constant, the performance cost is irrelevant.
There's now java.util.HexFormat which lets you do
byte[] CDRIVES = HexFormat.of().parseHex("e04fd020ea3a6910a2d808002b30309d");
This utility class lets you specify a format which is handy if you find other formats easier to read or when you're copy-pasting from a reference source:
byte[] CDRIVES = HexFormat.ofDelimiter(":") .parseHex("e0:4f:d0:20:ea:3a:69:10:a2:d8:08:00:2b:30:30:9d");
byte[] CDRIVES = hexStringToByteArray("e04fd020ea3a6910a2d808002b30309d");
I insert it here for maximum readability :
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) return data; >
answered Jun 26, 2012 at 13:43
Denys Séguret Denys Séguret
380k 90 90 gold badges 808 808 silver badges 773 773 bronze badges
In Java 17, you can now use java.util.HexFormat.of().parseHex("e04fd020ea3a6910a2d808002b30309d")
Commented Dec 1, 2021 at 3:22
byte[] myvar = "Any String you want".getBytes();
String literals can be escaped to provide any character:
byte[] CDRIVES = "\u00e0\u004f\u00d0\u0020\u00ea\u003a\u0069\u0010\u00a2\u00d8\u0008\u0000\u002b\u0030\u0030\u009d".getBytes();
1,116 1 1 gold badge 11 11 silver badges 25 25 bronze badges
answered Jan 15, 2014 at 18:50
1,741 1 1 gold badge 10 10 silver badges 4 4 bronze badges
Doesn't that turn the string "0000" to <0x30,0x30,0x30,0x30>(ASCII) rather than (binary) as desired by the poster?0x30,0x30,0x30,0x30>
Commented Aug 31, 2014 at 15:57
Look at the question's title. Then look back at this answer. Now tell me, what's wrong about it? It might not solve the poster's particular issue, but it sure solved mine. I needed to transform a string into a byte array to use as a seed for a pseudorandom number generator and this worked like a charm.
Commented Sep 14, 2018 at 15:55@e18r It is generating bytes, yes, but you don't know which since this depence on the default charset. At least use .getBytes(desiredEncoding).
Commented Feb 27, 2019 at 18:25@petmez dumb question: in JAVA, is something like "".getBytes(UTF_8)); (getBytes on an empty string) a safe thing to do? is it 'legal'? Or can I just do: = new byte[0]; ?
Commented Mar 1, 2019 at 18:35 @RobertAchmann "".getbytes("UTF-8") should return an empty array and is perfectly legal. Commented May 6, 2020 at 14:14In Java 6, there is a method doing exactly what you want:
private static final byte[] CDRIVES = javax.xml.bind.DatatypeConverter.parseHexBinary("e04fd020ea3a6910a2d808002b30309d")
Alternatively you could use Google Guava:
import com.google.common.io.BaseEncoding; private static final byte[] CDRIVES = BaseEncoding.base16().lowerCase().decode("E04FD020ea3a6910a2d808002b30309d".toLowerCase());
The Guava method is overkill, when you are using small arrays. But Guava has also versions that can parse input streams. This is a nice feature when dealing with big hexadecimal inputs.
25.4k 15 15 gold badges 77 77 silver badges 79 79 bronze badges answered Oct 8, 2013 at 8:12 stefan.schwetschke stefan.schwetschke 8,932 1 1 gold badge 27 27 silver badges 30 30 bronze badgesThe Guava example doesn't quite work as written - it needs to be base16().lowerCase().decode(. ) if you have lower case hex digits. docs.guava-libraries.googlecode.com/git/javadoc/com/google/…
Commented Sep 1, 2015 at 21:43@PeterDeGlopper Good finding, I've updated the answer so the code now handles strings with both lower and upper case characters.
Commented Sep 2, 2015 at 7:06 javax.xml.bind was sadly removed in Java 9. Commented Jan 5, 2019 at 22:02You can use the Java UUID class to store these values, instead of byte arrays:
UUID public UUID(long mostSigBits, long leastSigBits)
Constructs a new UUID using the specified data. mostSigBits is used for the most significant 64 bits of the UUID and leastSigBits becomes the least significant 64 bits of the UUID.
answered Jun 26, 2012 at 13:36 3,255 1 1 gold badge 17 17 silver badges 28 28 bronze badgesSmallest internal type, which at compile time can be assigned by unsigned hex numbers is char, as
private static final char[] CDRIVES_char = new char[] ;
In order to have an equivalent byte array one might deploy conversions as
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; >
answered Apr 19, 2020 at 11:57
Sam Ginrich Sam Ginrich
779 1 1 gold badge 7 7 silver badges 10 10 bronze badges
A solution with no libraries, dynamic length returned, unsigned integer interpretation (not two's 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 >; > >
answered Nov 10, 2017 at 20:49
304 2 2 silver badges 9 9 bronze badges
You can use this utility function:
public static byte[] fromHexString(String src)
Unlike variants of Denys Séguret and stefan.schwetschke, it allows inserting separator symbols (spaces, tabs, etc.) into the input string, making it more readable.
Example of usage:
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");