Создание строки ISO-8859-1 из HEX-строки в Java, сдвиг битов
-
06-07-2019 - |
Вопрос
Я пытаюсь преобразовать 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);
}
Кажется, это работает нормально для меня, но у меня все еще есть два вопроса по этому поводу:
- Есть ли более простой способ (желательно без обработки битов) выполнить это преобразование?
- Как мне интерпретировать строку:
int value = (high << 4) | low;
?
Я знаком с основами обработки битов, но совсем не знаком с синтаксисом Java.Я считаю, что первая часть сдвигает все биты влево на 4 шага.Хотя остальное я не понимаю и почему это может быть полезно в данной конкретной ситуации.
Прошу прощения за путаницу в моем вопросе, пожалуйста, дайте мне знать, если мне нужно что-то уточнить.Спасибо.//Abeansits
Решение
Есть ли более простой способ (желательно без обработки битов) выполнить это преобразование?
Ничего, о чем я бы не знал - единственное упрощение, похоже, анализирует весь байт сразу, а не анализирует цифру за цифрой (например,с использованием 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) | низкий;?
посмотрите на этот пример для ваших последних двух цифр (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
Другие советы
Вы можете заменить <<
и |
в этом случае на *
и +
, но я этого не рекомендую.
Выражение
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);
Есть ли более простой способ (желательно без обработки битов), чтобы сделать это преобразование?
Вы можете использовать Hex класс в Apache Commons, но внутри он будет делать то же самое, возможно, с небольшими отличиями.
Как мне интерпретировать строку:
int value = (high << 4) | low;
?
Это объединяет две шестнадцатеричные цифры, каждая из которых представляет 4 бита, в одно 8-битное значение без знака, сохраняемое как int
. Следующие две строки преобразуют это в подписанную Java byte
.