Строка в двоичный файл и наоборот: расширенный ASCII - PullRequest
2 голосов
/ 04 апреля 2011

Я хочу преобразовать строку в двоичный файл, поместив его в байтовый массив (String.getBytes[]), а затем сохранить двоичную строку для каждого байта (Integer.toBinaryString(bytearray)) в строке [].Затем я хочу преобразовать обратно в обычную строку через Byte.parseByte(stringarray[i], 2).Это прекрасно работает для стандартной таблицы ASCII, но не для расширенной.Например, A дает мне 1000001, а Ä возвращает

11111111111111111111111111000011
11111111111111111111111110000100

Есть идеи, как с этим справиться?

public class BinString {
    public static void main(String args[]) {
        String s = "ä";
        System.out.println(binToString(stringToBin(s)));

    }

    public static String[] stringToBin(String s) {
        System.out.println("Converting: " + s);
        byte[] b = s.getBytes();
        String[] sa = new String[s.getBytes().length];
        for (int i = 0; i < b.length; i++) {
            sa[i] = Integer.toBinaryString(b[i] & 0xFF);
        }
        return sa;
    }

    public static String binToString(String[] strar) {
        byte[] bar = new byte[strar.length];
        for (int i = 0; i < strar.length; i++) {
            bar[i] = Byte.parseByte(strar[i], 2);
            System.out.println(Byte.parseByte(strar[i], 2));

        }
        String s = new String(bar);
        return s;
    }

}

Ответы [ 2 ]

8 голосов
/ 04 апреля 2011

Во-первых: «расширенный ASCII» - очень вводящий в заблуждение заголовок, который используется для обозначения множества различных кодировок.

Второй: byte в Java подписано, тогда как байты в кодировках обычно обрабатываются какбез знака.Поскольку вы используете Integer.toBinaryString(), byte будет преобразован в int с использованием расширения знака (поскольку байтовые значения> 127 будут представлены отрицательными значениями в Java).

Чтобы избежать этого, просто используйте & 0xFF чтобы замаскировать все, кроме младшего 8 бита, вот так:

String binary = Integer.toBinaryString(byteArray[i] & 0xFF);
1 голос
/ 04 апреля 2011

Чтобы расширить на точку Иоахима о "расширенной ASCII", я бы добавил ...

Обратите внимание, что getBytes() - это операция транскодирования, которая преобразует данные из UTF-16 в кодировку платформы по умолчанию. Кодировка варьируется от системы к системе, а иногда даже между пользователями на одном ПК. Это означает, что результаты не согласованы на всех платформах, и если устаревшая кодировка используется по умолчанию (как в Windows), данные могут быть потеряны.

Чтобы сделать операцию симметричной, вам необходимо явно предоставить кодировку (предпочтительно кодировку Unicode, такую ​​как UTF-8 или UTF-16.)

Charset encoding = Charset.forName("UTF-16");
byte[] b = s1.getBytes(encoding);
String s2 = new String(b, encoding);
assert s1.equals(s2);
...