Создание строки ISO-8859-1 из HEX-строки в Java, сдвиг битов - PullRequest
1 голос
/ 27 октября 2009

Я пытаюсь преобразовать HEX-последовательность в строку, закодированную в ISO-8859-1, UTF-8 или UTF-16BE. То есть у меня есть строка, похожая на: "0422043504410442", которая представляет символы: "Test" в UTF-16BE.

Код, который я использовал для преобразования между двумя форматами, был:

private static String hex2String(String hex, String encoding) throws UnsupportedEncodingException {
    char[] hexArray = hex.toCharArray();

    int length = hex.length() / 2;
    byte[] rawData = new byte[length];
    for(int i=0; i<length; i++){
        int high = Character.digit(hexArray[i*2], 16);
        int low = Character.digit(hexArray[i*2+1], 16);
        int value = (high << 4) | low;
        if( value > 127)
                value -= 256;
        rawData[i] = (byte) value;
    }
    return new String(rawData, encoding);
}

Мне кажется, это работает нормально, но у меня все еще есть два вопроса по этому поводу:

  1. Есть ли более простой способ (желательно без обработки битов) сделать это преобразование?
  2. Как мне интерпретировать строку: int value = (high << 4) | low;?

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

Я прошу прощения за путаницу в моем вопросе, пожалуйста, дайте мне знать, если я должен что-то прояснить. Спасибо. // Abeansits

Ответы [ 3 ]

2 голосов
/ 27 октября 2009

Есть ли какой-нибудь более простой способ (желательно без обработки битов) сделать это преобразование?

Нет, я бы знал - единственное упрощение, по-видимому, заключается в том, чтобы анализировать весь байт сразу, а не анализировать цифру за цифрой (например, используя int value = Integer.parseInt(hex.substring(i * 2, i * 2 + 2), 16);)

public static byte[] hexToBytes(final String hex) {
  final byte[] bytes = new byte[hex.length() / 2];
  for (int i = 0; i < bytes.length; i++) {
    bytes[i] = (byte) Integer.parseInt(hex.substring(i * 2, i * 2 + 2), 16);
  }
  return bytes;
}

Как мне интерпретировать строку: int value = (high << 4) | низкий; </strong>

посмотрите на этот пример, чтобы узнать последние две цифры (42):

int high = 4; // binary 0100
int low = 2; // binary 0010
int value = (high << 4) | low;

int value = (0100 << 4) | 0010; // shift 4 to left
int value = 01000000 | 0010; // bitwise or
int value = 01000010;
int value = 66; // 01000010 == 0x42 == 66
1 голос
/ 27 октября 2009

Есть ли более простой способ (желательно без обработки битов), чтобы сделать это преобразование

Вы можете использовать класс Hex в Apache Commons, но внутри он будет делать то же самое, возможно, с небольшими различиями.

Как мне интерпретировать строку: int value = (high << 4) | low;?

Это объединяет две шестнадцатеричные цифры, каждая из которых представляет 4 бита, в одно 8-битное значение без знака, сохраняемое как int. Следующие две строки преобразуют это в подписанную Java byte.

1 голос
/ 27 октября 2009

Вы можете заменить << и | в этом случае на * и +, но я не рекомендую это.

Выражение

int value = (high << 4) | low;

эквивалентно

int value = high * 16 + low;

Вычитание 256 для получения значения между -128 и 127 не требуется. Простое приведение, например, 128 к байту даст правильный результат. 8 младших битов int 128 имеют тот же шаблон, что и byte -128: 0x80.

Я бы написал это просто:

rawData[i] = (byte) ((high << 4) | low);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...