Вопрос-ответ

Convert a string representation of a hex dump to a byte array using Java?

Преобразовать строковое представление шестнадцатеричного дампа в массив байтов с помощью Java?

Я ищу способ преобразовать длинную строку (из дампа), представляющую шестнадцатеричные значения, в массив байтов.

Я не смог бы сформулировать это лучше, чем человек, который разместил здесь тот же вопрос.

Но чтобы сохранить оригинальность, я сформулирую это по-своему: предположим, у меня есть строка, "00A0BF" которую я хотел бы интерпретировать как

byte[] {0x00,0xA0,0xBf}

что мне делать?

Я новичок в Java и в конечном итоге использовал BigInteger и следил за начальными шестнадцатеричными нулями. Но я думаю, что это некрасиво, и я уверен, что мне не хватает чего-то простого.

Переведено автоматически
Ответ 1

Обновление (2021) - Java 17 теперь включает java.util.HexFormat (потребовалось всего 25 лет):

HexFormat.of().parseHex(s)


Для более старых версий Java:

Вот решение, которое, я думаю, лучше любого опубликованного до сих пор:

/* s must be an even-length string. */
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;
}

Причины, по которым это улучшение:


  • Безопасно с начальными нулями (в отличие от BigInteger) и с отрицательными байтовыми значениями (в отличие от Byte.parseByte)



  • Не преобразует строку в char[] и не создает StringBuilder и объекты String для каждого отдельного байта.



  • Нет зависимостей библиотеки, которые могут быть недоступны



Не стесняйтесь добавлять проверку аргументов через assert или исключения, если известно, что аргумент небезопасен.

Ответ 2

Однострочники:

import javax.xml.bind.DatatypeConverter;

public static String toHexString(byte[] array) {
return DatatypeConverter.printHexBinary(array);
}

public static byte[] toByteArray(String s) {
return DatatypeConverter.parseHexBinary(s);
}

Предупреждения:


  • в Java 9 Jigsaw это больше не является частью (по умолчанию) java.se корневой набор, поэтому это приведет к исключению ClassNotFoundException, если вы не укажете --add-modules java.se.ee (спасибо @eckes)

  • Недоступно на Android (спасибо Fabian за замечание), но вы можете просто взять исходный код, если в вашей системе по какой-либо причине отсутствует javax.xml. Спасибо @Bert Regelink за извлечение исходного кода.

Ответ 3

Класс Hex в commons-codec должен сделать это за вас.

http://commons.apache.org/codec/

import org.apache.commons.codec.binary.Hex;
...
byte[] decoded = Hex.decodeHex("00A0BF");
// 0x00 0xA0 0xBF
Ответ 4

Теперь вы можете использовать BaseEncoding в guava для достижения этой цели.

BaseEncoding.base16().decode(string);

Чтобы изменить это, используйте

BaseEncoding.base16().encode(bytes);
java