Мне нужно сохранить некоторые постоянные значения (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" };
"0000"
в{0x30,0x30,0x30,0x30}
(ASCII), а не в{0x00,0x00,0x00,0x00}
(двоичный), как того требует плакат?В 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 есть также версии, которые могут анализировать входные потоки. Это удобная функция при работе с большими шестнадцатеричными входными данными.
источник
base16().lowerCase().decode(...)
если у вас есть шестнадцатеричные цифры нижнего регистра. docs.guava-libraries.googlecode.com/git/javadoc/com/google/…javax.xml.bind
был, к сожалению, удален в Java 9.Вы можете использовать класс Java UUID для хранения этих значений вместо байтовых массивов:
UUID public UUID(long mostSigBits, long leastSigBits)
Создает новый UUID, используя указанные данные. mostSigBits используется для 64 старших разрядов UUID, а lessSigBits становится 64 младшими битами UUID.
источник
Решение без библиотек, возвращаемая динамическая длина, беззнаковая целочисленная интерпретация (не дополнение до двух)
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 }; } }
источник
Что касается чистого процесса, вы можете использовать объект ByteArrayOutputStream ...
ByteArrayOutputStream bObj = new ByteArrayOutputStream(); bObj.reset();
// записываем все значения в bObj одно за другим, используя
bObj.write(byte value)
// когда закончите, вы можете получить byte [], используя
// чем вы можете повторить аналогичный процесс для CMYDOCS и IEFRAME,
ПРИМЕЧАНИЕ. Это не эффективное решение, если у вас действительно небольшой массив.
источник
Наименьший внутренний тип, который во время компиляции может быть назначен шестнадцатеричными числами, - это char , так как
private static final char[] CDRIVES_char = new char[] {0xe0, 0xf4, ...};
Чтобы иметь эквивалентный массив байтов, можно развернуть преобразования как
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; }
источник
В этом случае я предпочитаю использовать
org.apache.commons.codec.binary.Hex
который имеет полезные API для преобразования междуString
шестнадцатеричным y и двоичным. Например:Hex.decodeHex(char[] data)
который выдает a,DecoderException
если в массиве есть не шестнадцатеричные символы или если есть нечетное количество символов.Hex.encodeHex(byte[] data)
является аналогом метода декодирования, описанного выше, и выводит расширениеchar[]
.Hex.encodeHexString(byte[] data)
который преобразуется обратно изbyte
массива вString
.Применение:
Hex.decodeHex("dd645a2564cbe648c8336d2be5eafaa6".toCharArray())
источник
Вы можете использовать эту служебную функцию:
public static byte[] fromHexString(String src) { byte[] biBytes = new BigInteger("10" + src.replaceAll("\\s", ""), 16).toByteArray(); return Arrays.copyOfRange(biBytes, 1, biBytes.length); }
В отличие от вариантов Denys Sé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");
источник
private static final int[] CDRIVES = new int[] {0xe0, 0xf4, ...};
и после обращения конвертируем в байт.
источник