Я ищу способ конвертировать длинную строку (из дампа), которая представляет шестнадцатеричные значения в байтовом массиве.
Я не мог бы сформулировать это лучше, чем человек, который разместил здесь тот же вопрос .
Но чтобы сохранить оригинальность, я сформулирую это по-своему: предположим, у меня есть строка, "00A0BF"
которую я хотел бы интерпретировать как
byte[] {0x00,0xA0,0xBf}
что мне делать?
Я новичок в Java и в итоге использовал BigInteger
и следил за ведущими шестнадцатеричными нулями. Но я думаю, что это ужасно, и я уверен, что упускаю что-то простое.
BigInteger
здесь .String.getBytes()
не будет работать так, как вы думаете. Пришлось научиться этому нелегкому пути.if ("FF".getBytes() != "ff".getBytes()) { System.out.println("Try again"); }
Ответы:
Вот решение, которое я считаю лучше, чем любое опубликованное до сих пор:
Причины, почему это улучшение:
Сейф с ведущими нулями (в отличие от BigInteger) и с отрицательными значениями байтов (в отличие от Byte.parseByte)
Не преобразует String в a
char[]
и не создает объекты StringBuilder и String для каждого байта.Нет библиотечных зависимостей, которые могут быть недоступны
Не стесняйтесь добавлять проверку аргументов с помощью
assert
или исключений, если аргумент не известен как безопасный.источник
Однострочники:
Предупреждения :
eckes
)Fabian
обратили на это внимание), но вы можете просто взять исходный код, если вашей системеjavax.xml
по какой-то причине не хватает . Спасибо @Bert Regelink
за извлечение источника.источник
java.se
корневого набора, поэтому оно приведет к тому, чтоClassNotFoundException
если вы не укажете--add-modules java.se.ee
javax.xml.bind.DatatypeConverter
уже предоставляет метод для кодирования / декодирования данных Base64. СмотритеparseBase64Binary()
иprintBase64Binary()
.DataTypeConverter
, Java SE 11 полностью удалил JAXB API и теперь включен только в Java EE. Вы также можете добавить его как зависимость Maven, как это предлагается здесь: stackoverflow.com/a/43574427/7347751Класс Hex в commons-codec должен сделать это за вас.
http://commons.apache.org/codec/
источник
Теперь вы можете использовать BaseEncoding в
guava
для достижения этой цели .Чтобы изменить это, используйте
источник
На самом деле, я думаю, что BigInteger - это очень хорошее решение:
Изменить: Не безопасно для ведущих нулей , как отмечено на плакате.
источник
Для тех из вас, кто интересуется реальным кодом One-liners от FractalizeR (мне нужно было это, поскольку javax.xml.bind недоступен для Android (по умолчанию)), это происходит из com.sun.xml.internal.bind. DatatypeConverterImpl.java :
источник
HexBinaryAdapter
Предоставляет возможность маршала и распаковать междуString
иbyte[]
.Это просто пример, который я напечатал ... Я на самом деле просто использую его как есть, и мне не нужно создавать отдельный метод для его использования.
источник
Вот метод, который действительно работает (основан на нескольких предыдущих полу-правильных ответах):
Единственная возможная проблема, которую я вижу, - это если строка ввода очень длинная; вызов toCharArray () создает копию внутреннего массива строки.
РЕДАКТИРОВАТЬ: Да, и, кстати, байты подписаны в Java, поэтому ваша входная строка преобразуется в [0, -96, -65] вместо [0, 160, 191]. Но вы, наверное, уже знали это.
источник
В Android, если вы работаете с hex, вы можете попробовать Okio .
простое использование:
и результат будет
источник
BigInteger()
Метод от java.math очень медленно и не рекомендуем.Integer.parseInt(HEXString, 16)
может вызвать проблемы с некоторыми символами без преобразования в цифру / целое число
Хорошо работающий метод:
Функция:
Удачи, удачи
источник
РЕДАКТИРОВАНИЕ: как указано @mmyers, этот метод не работает на вводе, который содержит подстроки, соответствующие байтам с установленным старшим битом ("80" - "FF"). Объяснение приведено в сообщении об ошибке: 6259307 Byte.parseByte не работает, как указано в документации SDK .
источник
Для чего стоит, вот еще одна версия, которая поддерживает строки нечетной длины, не прибегая к конкатенации строк.
источник
Я всегда использовал такой метод, как
этот метод разбивает на шестнадцатеричные значения, разделенные пробелом, но нетрудно разбить строку по любому другому критерию, например, по группам из двух символов.
источник
Byte
/byte
case: старший бит установлен без старта -)Мне нравится решение Character.digit, но вот как я его решил
источник
Кодекс, представленный Бертом Регелинком, просто не работает. Попробуйте следующее:
источник
Я обнаружил, что Kernel Panic предлагает наиболее полезное для меня решение, но столкнулся с проблемами, если шестнадцатеричная строка была нечетным числом. решил это так:
Я добавляю количество шестнадцатеричных чисел в массив, поэтому я передаю ссылку на массив, который я использую, и int мне нужно преобразовать и вернуть относительную позицию следующего шестнадцатеричного числа. Таким образом, последний байтовый массив имеет [0] количество шестнадцатеричных пар, [1 ...] шестнадцатеричных пар, затем количество пар ...
источник
Основываясь на предложенном решении, следующее должно быть немного более эффективным:
Потому что: первоначальное преобразование в массив char избавляет от проверки длины в charAt
источник
Если в качестве стиля кодирования вы предпочитаете потоки Java 8, этого можно достичь, используя только примитивы JDK.
В
, 0, s2.size()
параметрах функции коллектора конкатенации могут быть опущены , если вы не против ловлиIOException
.источник
источник
Мое официальное решение:
Это как функция PHP hex2bin (), но в стиле Java.
Пример:
источник
Поздно к вечеринке, но я объединил приведенный выше ответ DaveL в класс с обратным действием - на всякий случай, если это поможет.
И тестовый класс JUnit:
источник
Я знаю, что это очень старая тема, но все равно хотел бы добавить свою копейку.
Если мне действительно нужно кодировать простую шестнадцатеричную строку в двоичный преобразователь, я бы хотел сделать это следующим образом.
источник
Далеко не самое чистое решение. Но это работает для меня и хорошо отформатировано:
Выход:
источник
Я думаю, сделаю это за вас. Я собрал его вместе из аналогичной функции, которая возвращала данные в виде строки:
источник
Для меня это было решение, HEX = "FF01", затем разделить на FF (255) и 01 (01)
источник