На нашем сайте мы используем cookie для сбора информации технического характера и обрабатываем IP-адрес вашего местоположения. Продолжая использовать этот сайт, вы даете согласие на использование файлов cookies. Здесь вы можете узнать, как мы пользуемся файлами cookies.
Я согласен
логотип upread.ru

Кодирование и декодирование base64 на Java 8


Base64 - схема кодирования, которая позволяет перевести двоичные данные в строку формата ASCII и наоборот. Каждый знак в base64 – это 6 бит двоичных данных. Java 8 дает возможность управлять таким преобразованием.

Base64 используется для предотвращения данных от изменения в процессе передачи посредством информационных систем, таких как электронная почта, которая не может быть 8-битной (они могут исказить 8-битные значения). Например, вы прикрепляете изображение к сообщению электронной почты и хотите, чтобы отправленные и доставленные изображения не отличались. Ваша программа электронной почты в base64 кодирует изображение и вставляет эквивалентный текст в сообщение, как показано ниже:

Content-Disposition: inline;
	filename=IMG_0006.JPG
Content-Transfer-Encoding: base64
/9j/4R/+RXhpZgAATU0AKgAAAAgACgEPAAIAAAAGAAAAhgEQAAIAAAAKAAAAjAESAAMAAAABAAYA
AAEaAAUAAAABAAAAlgEbAAUAAAABRRRngEoAAMAAAABAAIAAAExAAIAAAAHAAAApgEyAAIAAAAU
AAAArgITAAMAAAABAAEAAIdpAAQAAAABAAAAwgAABCRBcHBsZQBpUGhvbmUgNnMAAAAASAAAAAEA
...
NOMbnDUk2bGh2yy2yiJcsoBIrvtPe3muBbTRGMdeufmH+Nct4chUXpwSPk/qK9GtJRMWWVFbZ0JH
I4rf2dkZSbOjt7hhEzwcujA4I7Gust75pYVwAPpXn+kzNLOVYD7xFegWEKPkHsM/pU1F0NKbNS32
o24sSCOlaaFYLUhjky4x9PSsKL4UJsdWkAz3xirH2dZLy1DM2C44zx1FZqL2PTXY/9k=
Вы можете видеть, что закодированное изображение начинается с / и заканчивается =. Многоточие означает, что весь текст не показан для краткости. Обратите внимание, что такая кодировка будет больше объемом на 33% чем двоичные данные.

Работа с base64 в java

В Java 8 есть base64 интерфейс API. Он состоит из java.util.Base64 классов вместе со своими Encoder и Decoder вложенные static классы. В Base64 представлено несколько static методов для получения кодеров и декодеров:

  • Base64.Encoder getEncoder(): Возвращает энкодер для базового варианта.
  • Base64.Decoder getDecoder(): Возвращаете декодер для базового варианта.
  • Base64.Encoder getMimeEncoder(): Возвращает энкодер для варианта Mime.
  • Base64.Encoder getMimeEncoder(int lineLength, byte[] lineSeparator): Возвращает энкодер для модифицированных МИМ вариант с lineLength (с округлением вниз до ближайшего кратного 4 -- вывод не разделяется на линии при lineLength <= 0) и lineSeparator.
  • Base64.Decoder getMimeDecoder(): Возвращает декодер для варианта Mime.
  • Base64.Encoder getUrlEncoder(): Возвращает энкодер для URL-адрес и имя безопасный вариант.
  • Base64.Decoder getUrlDecoder(): Возвращает декодер для URL-адрес и имя безопасный вариант.
  • Base64.Encoder представлено многопоточное выполнение методов экземпляра для кодирования последовательности байтов.
Hello, Base64

API с помощью base64 на Java прост в использовании. Рассмотрим программу в стиле «Здравствуй, Мир!», которая при помощи base64 кодирует сообщение с помощью базового кодера, а затем осуществляет base64-декодирование. В листинге 1 представлен исходный код:

import java.util.Base64;

public class HelloBase64
{
   public static void main(String[] args)
   {
      String msg = "Hello, Base64!";
      Base64.Encoder enc = Base64.getEncoder();
      byte[] encbytes = enc.encode(msg.getBytes());
      for (int i = 0; i < encbytes.length; i++)
      {
         System.out.printf("%c", (char) encbytes[i]);
         if (i != 0 && i % 4 == 0)
            System.out.print(' ');
      }
      System.out.println();
      Base64.Decoder dec = Base64.getDecoder();
      byte[] decbytes = dec.decode(encbytes);
      System.out.println(new String(decbytes));
   }
}
Результат:

SGVsb G8sI EJhc 2U2N CE=
Hello, Base64!
Кодирование и декодирование файлов на Java

base64 более полезно для кодирования файлов. Я создал второе приложение, которое демонстрирует эта полезность наряду с base64 API-интерфейсом. В листинге 2 представлен исходный код приложения.

import java.io.*;
import java.util.Base64;

public class FileEncDec
{
   public static void main(String[] args)
   {
      if (args.length != 1)
      {
         System.err.println("Format: java FileEncDec filename");
         return;
      }
      try (FileInputStream fis = new FileInputStream(args[0]))
      {
         Base64.Encoder enc1 = Base64.getEncoder();
         Base64.Encoder enc2 = Base64.getMimeEncoder();
         Base64.Encoder enc3 = Base64.getUrlEncoder();
         OutputStream os1 = enc1.wrap(new FileOutputStream(args[0] + "1.enc"));
         OutputStream os2 = enc2.wrap(new FileOutputStream(args[0] + "2.enc"));
         OutputStream os3 = enc3.wrap(new FileOutputStream(args[0] + "3.enc"));
         int _byte;
         while ((_byte = fis.read()) != -1)
         {
            os1.write(_byte);
            os2.write(_byte);
            os3.write(_byte);
         }
         os1.close();
         os2.close();
         os3.close();
      }
      catch (IOException ioe)
      {
         System.err.printf("I/O error: %s%n", ioe.getMessage());
      }
      try (FileOutputStream fos1 = new FileOutputStream("1" + args[0]);
           FileOutputStream fos2 = new FileOutputStream("2" + args[0]);
           FileOutputStream fos3 = new FileOutputStream("3" + args[0]))
      {
         Base64.Decoder dec1 = Base64.getDecoder();
         Base64.Decoder dec2 = Base64.getMimeDecoder();
         Base64.Decoder dec3 = Base64.getUrlDecoder();
         InputStream is1 = dec1.wrap(new FileInputStream(args[0] + "1.enc"));
         InputStream is2 = dec2.wrap(new FileInputStream(args[0] + "2.enc"));
         InputStream is3 = dec3.wrap(new FileInputStream(args[0] + "3.enc"));
         int _byte;
         while ((_byte = is1.read()) != -1)
            fos1.write(_byte);
         while ((_byte = is2.read()) != -1)
            fos2.write(_byte);
         while ((_byte = is3.read()) != -1)
            fos3.write(_byte);
         is1.close();
         is2.close();
         is3.close();
      }
      catch (IOException ioe)
      {
         System.err.printf("I/O error: %s%n", ioe.getMessage());
      }
   }
}
В FileEncDec приложение требует имя файла в качестве одиночного аргумента командной строки.. Каждый байт записывается в другой файл с помощью разных энкодера и выходного потока. Позже, эти файлы открываются и читаются через разные декодеры и входных потоков. Результаты хранятся в трех отдельных файлах.

Запустите полученное приложение следующим образом (предполагается, у вас есть в формате JPEG-файл с именем image.jpg):

base64 на Java 8

java FileEncDec image.jpg
Вы увидите image.jpg1.enc, image.jpg2.enc и image.jpg3.enc файлы в текущем каталоге. В файлах формата .enc текстовое содержимое бинарных файлов. Разница между image.jpg1.enc и image.jpg3.enc в том, что каждый / был заменен _ , и каждый + был заменен на -. Также вы можете наблюдать три файла: 1image.jpg, 2image.jpg и 3image.jpg. Каждый из этих файлов содержит идентичный контент image.jpg.

Интересное в base64

А давайте попробуем в одном из файлов (image.jpg2.enc) заменить всего один символ. Скажем, где-нибудь в середине заменим R на A – один из тысяч символов. Думаете, это что-то изменит? И в нашей программе закомментируем запись в файл image. jpg2.enc, чтобы только прочитало наш закодированный и восстановило по нему картинку. Смотрите сами изменения:

base64 ошибочный

Есть отличие, не правда ли? Теперь вы понимаете, почему в начале статьи я написал о важности передачи без искажений? Если у вас есть вопросы по статье или необходимо написать программу на Java, То вы можете обратиться ко мне – за небольшую плату я вам с удовольствием помогу.



тегистатьи IT, java, base64, кодирование





Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.




Роман "Работа во сне": Глава №2
Работа с джойстиком в C#: часть 1


© upread.ru 2013-2019
При перепечатке активная ссылка на сайт обязательна.
Задать вопрос
письмо
Здравствуйте! Вы можете задать мне любой вопрос. Если не получается отправить сообщение через эту форму, то пишите на почу up777up@yandex.ru
Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.