Как кодировать шестнадцатеричный код в строку с помощью кодировки ISO-8859-6?

#java #encoding #character-encoding #binary #ascii

Вопрос:

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

У меня есть много двоичных файлов, содержащих различные типы данных, которые необходимо отобразить(ASCII, hex ..).

Поэтому мой обычный метод отображения значений ASCII-это использование ISO-8859-1, включенного в класс StandardCharsets. К сожалению, он не поддерживает стандарт iso-8859.6, в котором необходимо отображать арабские символы. Вот мои методы, используемые для кодирования:

Первый метод дает мне шестнадцатеричные коды в виде строки:

 public static String hexField(byte[] record, int offset, int length) {
     StringBuilder s = new StringBuilder(length * 2);
     int end = offset   length;

     for (int i = offset; i < end; i  ) {
         int high_nibble = (record[i] amp; 0xf0) >>> 4;
         int low_nibble = (record[i] amp; 0x0f);
         s.append(hex_table[high_nibble]);
         s.append(hex_table[low_nibble]);
         
     }

     return s.toString();
}
 

Второй метод: Отображает поле ASCII, используя предыдущий метод:

 private static String asciiField(byte[] record, int offset, int length) throws UnsupportedEncodingException {
    String field = hexField(record, offset, length) ; 
    
    byte[] fieldByte = javax.xml.bind.DatatypeConverter.parseHexBinary(field);
    return new String(fieldByte,StandardCharsets.ISO_8859_1).trim() ;
}
 

Как я могу отображать арабские символы, закодированные в iso-8859.6 Спасибо !

Комментарии:

1. Кажется, есть некоторая путаница: значения ASCII-это значения ASCII. Значения ISO-8859- x являются значениями ISO-8859- x . Хотя существует перекрытие (в частности, кодировки ISO являются надмножеством кодека ASCII), как только вы включаете ISO-8859-1 (или -6), вам больше не нужно говорить об ASCII вообще. Кроме того, ваш asciiField метод совершенно излишне преобразует byte[] шестнадцатеричное представление в шестнадцатеричное представление, а это шестнадцатеричное представление обратно в a byte[] без видимого значения.

2. На самом деле вы правы ! На данный момент это было быстрое решение, на которое нужно обратить внимание. Спасибо, что указали мне на это.

Ответ №1:

Хотя стандарт ISO-8859-6 не обязательно должен поддерживаться стандартом Java SE (и, как таковой, не имеет соответствующей константы in StandardCharsets ), я считаю, что он широко поддерживается.

Чтобы использовать его, просто используйте строковую константу "ISO-8859-6" там, где требуется набор символов , например, для преобразования byte[] данных, содержащих ISO-8859-6, в a String , просто используйте

 byte[] byteData = {(byte) 0xC2, (byte) 0xD4, (byte) 0xD8};
String s = new String(byteData, "ISO-8859-6");
 

Это отлично работает на моей машине. ( byteData в этом примере почти наверняка содержится тарабарщина, так как я не знаю арабского языка, но он представляет некоторые арабские символы в ISO-8859-6).

В качестве альтернативы вы можете использовать Charset.forName("ISO-8859-6") , если хотите Charset иметь под рукой реальный объект. Это также перемещает объект UnsupportedEncodingException в место, где Charset.forName он вызывается, и не заполняет все byte[] String места преобразования в, за исключением этого.

Также, пожалуйста, обратите внимание, что hexField , по-видимому, происходит полная противоположность parseHexBinary тому, чтобы эти два метода, связанные вместе, были бессмысленными byte[] — >шестнадцатеричное представление — >>>> цепочка byte[] преобразования. Существует даже String конструктор, который принимает смещение и длину, которые вы могли бы использовать:

 private static final Charset ISO_8859_6 = Charset.forName("ISO-8859-6");

private static String textField(byte[] record, int offset, int length) {
    return new String(record, offset, length, ISO_8859_6).trim() ;
}
 

Комментарии:

1. Я приношу извинения за поздний ответ. Предоставленное решение дало мне «???». Я разберусь в этом подробнее! Спасибо, сэр

2. @ZiedOrabi: обратите внимание, что это ??? может указывать на то, что везде, куда вы выводите , символы не поддерживаются. Попробуйте сбросить отдельные кодовые точки Юникода результирующей строки и проверить, являются ли они чем-то иным, чем 63/0x3F (что было бы ? ).

3. u622u634u638 . Я только что погуглил эти юникоды, и они определенно являются арабскими буквами. Это может быть проблема с консолью при печати. Моя главная цель-заполнить файл excel арабским контентом из двоичного файла. Я попытаюсь проверить, могу ли я изменить кодировку в файле excel. Что касается этого вопроса, то ваш ответ явно верен, а остальное-моя работа. Большое спасибо!

4. На всякий случай, если тебе было любопытно. Я исправил это, добавив эту строку. Строка[] word = s1.split(«\\»); для (int i = 0 ; i длина ; i ) { System.out.println(слово[i]); }