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

Указатель NULL - это тот, который указывает на никуда. Когда вы разыскиваете указатель p, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p является нулевым указателем, местоположение, хранящееся в p, является nowhere, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception.

В общем, это потому, что что-то не было правильно инициализировано.

353
задан rafraf 28 July 2018 в 20:31
поделиться

10 ответов

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

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 и Строки для каждого байта.

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

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

607
ответ дан Dave L. 23 November 2019 в 00:23
поделиться

Я думаю, сделает это для Вас. Я починил его от подобной функции, которая возвратила данные как строку:

private static byte[] decode(String encoded) {
    byte result[] = new byte[encoded/2];
    char enc[] = encoded.toUpperCase().toCharArray();
    StringBuffer curr;
    for (int i = 0; i < enc.length; i += 2) {
        curr = new StringBuffer("");
        curr.append(String.valueOf(enc[i]));
        curr.append(String.valueOf(enc[i + 1]));
        result[i] = (byte) Integer.parseInt(curr.toString(), 16);
    }
    return result;
}
-2
ответ дан Bob King 23 November 2019 в 00:23
поделиться

Я всегда использовал метод как

public static final byte[] fromHexString(final String s) {
    String[] v = s.split(" ");
    byte[] arr = new byte[v.length];
    int i = 0;
    for(String val: v) {
        arr[i++] =  Integer.decode("0x" + val).byteValue();

    }
    return arr;
}

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

2
ответ дан pfranza 23 November 2019 в 00:23
поделиться

РЕДАКТИРОВАНИЕ: как указано @mmyers, этот метод не работает над входом, который содержит подстроки, соответствующие байтам с высоким набором битов ("80" - "FF"). Объяснение в идентификатор Ошибки: 6259307 Byte.parseByte, не работающие, как рекламируется в Документации SDK .

public static final byte[] fromHexString(final String s) {
    byte[] arr = new byte[s.length()/2];
    for ( int start = 0; start < s.length(); start += 2 )
    {
        String thisByte = s.substring(start, start+2);
        arr[start/2] = Byte.parseByte(thisByte, 16);
    }
    return arr;
}
4
ответ дан Blair Conrad 23 November 2019 в 00:23
поделиться

Вот метод, который на самом деле работает (на основе нескольких предыдущих полукорректных ответов):

private static byte[] fromHexString(final String encoded) {
    if ((encoded.length() % 2) != 0)
        throw new IllegalArgumentException("Input string must contain an even number of characters");

    final byte result[] = new byte[encoded.length()/2];
    final char enc[] = encoded.toCharArray();
    for (int i = 0; i < enc.length; i += 2) {
        StringBuilder curr = new StringBuilder(2);
        curr.append(enc[i]).append(enc[i + 1]);
        result[i/2] = (byte) Integer.parseInt(curr.toString(), 16);
    }
    return result;
}

единственная возможная проблема, которую я вижу, - то, если входная строка чрезвычайно длинна; вызов toCharArray () делает копию внутреннего массива строки.

РЕДАКТИРОВАНИЕ: О, и между прочим, байты подписываются в Java, таким образом, Ваша входная строка преобразовывает в [0,-96,-65] вместо [0, 160, 191]. Но Вы, вероятно, уже знали это.

14
ответ дан Michael Myers 23 November 2019 в 00:23
поделиться

На самом деле я думаю, что BigInteger является решением, очень хорошо:

new BigInteger("00A0BF", 16).toByteArray();

Редактирование: Не безопасный для начальных нулей , как отмечено плакатом.

27
ответ дан Dave L. 23 November 2019 в 00:23
поделиться

Шестнадцатеричный класс в кодеке свободного городского населения должен сделать это для Вас.

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

import org.apache.commons.codec.binary.Hex;
...
byte[] decoded = Hex.decodeHex("00A0BF");
// 0x00 0xA0 0xBF
75
ответ дан Utgarda 23 November 2019 в 00:23
поделиться

Метод BigInteger () из java.math очень медленный и не рекомендуется.

Integer.parseInt (HEXString, 16)

может вызвать проблемы с некоторые персонажи без преобразование в число / целое число

Хорошо работающий метод:

Integer.decode("0xXX") .byteValue()

Функция:

public static byte[] HexStringToByteArray(String s) {
    byte data[] = new byte[s.length()/2];
    for(int i=0;i < s.length();i+=2) {
        data[i/2] = (Integer.decode("0x"+s.charAt(i)+s.charAt(i+1))).byteValue();
    }
    return data;
}

Удачи, удачи

5
ответ дан 23 November 2019 в 00:23
поделиться
public static byte[] hex2ba(String sHex) throws Hex2baException {
    if (1==sHex.length()%2) {
        throw(new Hex2baException("Hex string need even number of chars"));
    }

    byte[] ba = new byte[sHex.length()/2];
    for (int i=0;i<sHex.length()/2;i++) {
        ba[i] = (Integer.decode(
                "0x"+sHex.substring(i*2, (i+1)*2))).byteValue();
    }
    return ba;
}
0
ответ дан 23 November 2019 в 00:23
поделиться

Мне нравится решение Character. digit, но вот как я решил эту проблему

public byte[] hex2ByteArray( String hexString ) {
    String hexVal = "0123456789ABCDEF";
    byte[] out = new byte[hexString.length() / 2];

    int n = hexString.length();

    for( int i = 0; i < n; i += 2 ) {
        //make a bit representation in an int of the hex value 
        int hn = hexVal.indexOf( hexString.charAt( i ) );
        int ln = hexVal.indexOf( hexString.charAt( i + 1 ) );

        //now just shift the high order nibble and add them together
        out[i/2] = (byte)( ( hn << 4 ) | ln );
    }

    return out;
}
2
ответ дан 23 November 2019 в 00:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: