Проблема с кодировкой / декодированием Base64: декодированной строкой является '?' - PullRequest
2 голосов
/ 26 июня 2011

Я пытаюсь прочитать изображение и использовать кодировку Base64 для преобразования его в байтовый массив, а затем в строку для отправки по сети. Проблема в том, что когда я пытаюсь декодировать строку в кодировке Base64, я получаю неверные данные.

Например, У меня проблема со специальным символом ниже.

Я использую следующий код для кодирования:

byte[] b = Base64.encodeBase64(IOUtils.toByteArray(loInputStream));
String ab = new String(b);

IOUtils - org.apache.commons.io.IOUtils.

и loInput

Код для декодирования:

byte[] c = Base64.decodeBase64(ab.getBytes());
String ca = new String(c);
System.out.println(ca);

Он печатает ? для расшифрованной строки.

Может кто-нибудь, пожалуйста, дайте мне знать проблему.

Ответы [ 2 ]

4 голосов
/ 26 июня 2011

Если ваш ввод является изображением, имеет смысл кодировать его как base64 - base64 является текстом и может быть представлен строкой.

Повторно расшифровав, вы получите исходное изображение.Изображение обычно представляет собой двоичный формат;нет смысла пытаться преобразовать это в строку - это не текст.

То есть последние 2 строки:

   String ca = new String(c);
   System.out.println(ca);

Просто не имеет смысла это делать.

Если вы хотите убедиться, что декодирование дает тот же вывод, что и исходный ввод, выполните, например,

  System.out.println("Original and decoded are the same: " + Arrays.equals(b,c));

(Или сохраните байтовый массив в файл и просмотрите изображение на изображениизритель)

2 голосов
/ 28 июня 2011

Как я уже сказал в другом месте , в Java String для текста, а byte[] для двоичных данных.

String ≠ byte []

Текст ≠ Двоичные данные

Изображение является двоичными данными. Base64 - это кодировка, которая позволяет передавать двоичные данные по текстовым каналам, совместимым с US_ASCII (аналогичное кодирование для надмножеств набора ASCII-текста: Quoted Printable).

Итак, это выглядит так:

Image (binary data) → Image (text, Base64 encoded binary data) → Image (binary data)

, где вы будете использовать String encodeBase64String(byte[]) для кодирования и byte[] decode(String) для декодирования. Это единственные вменяемые API для Base64, byte[] encodeBase64(byte[]) вводит в заблуждение, в результате получается US_ASCII-совместимый текст (так что String, не byte[]).

Теперь текст имеет кодировку и кодировку, String использует фиксированную комбинацию кодировки / кодировки Unicode / UTF-16 для внутреннего использования, и вы должны указать кодировку / кодировку при преобразовании чего-либо из / в String, либо явно, либо неявно, используя кодировку платформы по умолчанию (что и делает PrintStream.println()). Текст Base64 - это чистый US_ASCII, поэтому вам нужно использовать его или расширенный набор US_ASCII. org.apache.commons.codec.binary.Base64 использует UTF8, который является надмножеством US_ASCII, так что все хорошо. (OTOH, внутренний java.util.prefs.Base64 использует кодировку платформы по умолчанию, поэтому я думаю, что он сломается, если вы запустите JVM, скажем, с кодировкой UTF-16).

Вернемся к теме: вы пытались напечатать декодированное изображение (двоичные данные) в виде текста, что, очевидно, не сработало. PrintStream имеет write() методы, которые могут записывать двоичные данные, так что вы можете использовать их, и вы получите тот же мусор, что и при написании исходного изображения. Было бы гораздо лучше использовать FileOutputStream и сравнить полученный файл с исходным файлом изображения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...