Кодировка Unicode Base 64 с использованием Java - PullRequest
4 голосов
/ 18 апреля 2011

Я пытаюсь кодировать и декодировать строку UTF8 в base64. В теории это не проблема, но при декодировании и, кажется, никогда не выводятся правильные символы, кроме?.


        String original = "خهعسيبنتا";
        B64encoder benco = new B64encoder();
        String enc = benco.encode(original);
        try
        {
            String dec = new String(benco.decode(enc.toCharArray()), "UTF-8");
            PrintStream out = new PrintStream(System.out, true, "UTF-8");
            out.println("Original: " + original);
            prtHx("ara", original.getBytes());
            out.println("Encoded: " + enc);
            prtHx("enc", enc.getBytes());
            out.println("Decoded: " + dec);
            prtHx("dec", dec.getBytes());
        } catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }

Вывод на консоль следующий:

Оригинал: خهعسيبنتا
ara = 3F, 3F, 3F, 3F, 3F, 3F, 3F, 3F, 3F
Кодированный: Pz8 / Pz8 / Pz8 /
enc = 50, 7A, 38, 2F, 50, 7A, 38, 2F, 50, 7A, 38, 2F
Расшифровано: ?????????
dec = 3F, 3F, 3F, 3F, 3F, 3F, 3F, 3F, 3F

prtHx просто записывает шестнадцатеричное значение байтов в вывод. Я делаю что-то явно не так?


Андреас указал на правильное решение, подчеркнув, что метод getBytes () использует кодировку платформы по умолчанию (Cp1252), даже если сам исходный файл имеет формат UTF-8. Используя getBytes («UTF-8»), я смог заметить, что закодированные и декодированные байты на самом деле были разными. Дальнейшие исследования показали, что метод кодирования использовал getBytes (). Изменение этого сделало трюк хорошо.


try
        {
            String enc = benco.encode(original);
            String dec = new String(benco.decode(enc.toCharArray()), "UTF-8");
            PrintStream out = new PrintStream(System.out, true, "UTF-8");
            out.println("Original: " + original);
            prtHx("ori", original.getBytes("UTF-8"));
            out.println("Encoded: " + enc);
            prtHx("enc", enc.getBytes("UTF-8"));
            out.println("Decoded: " + dec);
            prtHx("dec", dec.getBytes("UTF-8"));

        } catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }

Системное кодирование Cp1252
Оригинал: خهعسيبنتا
ori = D8, AE, D9, 87, D8, B9, D8, B3, D9, 8A, D8, A8, D9, 86, D8, AA, D8, A7
Закодировано: 2K7Ж9i52LPZitio2YbYqtin

enc = 32, 4B, 37, 5A, 68, 39, 69, 35, 32, 4C, 50, 5A, 69, 74, 69, 6F, 32, 59, 62, 59, 71, 74, 69 , 6E
Расшифровано: خهعسيبنتا
dec = D8, AE, D9, 87, D8, B9, D8, B3, D9, 8A, D8, A8, D9, 86, D8, AA, D8, A7

Спасибо.

1 Ответ

6 голосов
/ 18 апреля 2011

String#getBytes() кодирует символы, используя кодировку платформы по умолчанию. Фактическая кодировка строкового литерала "خهعسيبنتا" «определена» в исходном файле Java (вы выбираете кодировку символов при создании или сохранении файла)

Это может быть причиной того, почему ara кодируется в 0x3f байт ..

Попробуйте:

out.println("Original: " + original);
prtHx("ara", original.getBytes("UTF-8"));
out.println("Encoded: " + enc);
prtHx("enc", enc.getBytes("UTF-8"));
out.println("Decoded: " + dec);
prtHx("dec", dec.getBytes("UTF-8"));
...