Кодирование и декодирование Java Base64

Кодирование и декодирование Java Base64

1. обзор

В этом руководстве мы собираемся изучить различные утилиты, которые предоставляют функции кодирования и декодирования Base64 в Java.

В основном мы собираемся проиллюстрировать новые API Java 8, а также служебные API, выходящие из Apache Commons.

Дальнейшее чтение:

Руководство по кодированию / декодированию URL Java

В статье обсуждается кодировка URL в Java, некоторые подводные камни и способы их устранения.

Read more

SHA-256 и SHA3-256 Хеширование в Java

Краткое и практическое руководство по хешированию SHA-256 в Java

Read more

Хранение нового пароля в Spring Security 5

Краткое руководство по пониманию шифрования паролей в Spring Security 5 и переходу к лучшим алгоритмам шифрования.

Read more

2. Java 8 для Base 64

Java 8 has finally added Base64 capabilities к стандартному API черезjava.util.Base64 utility class.

Начнем с рассмотрения базового процесса кодирования.

2.1. Java 8 Basic Base64

Базовый кодер упрощает работу и кодирует входные данные как есть - без разделения строк.

Вывод сопоставляется с набором символов в наборе символовA-Za-z0-9+/, и декодер отклоняет любой символ вне этого набора.

Давайте сначалаencode a simple String:

String originalInput = "test input";
String encodedString = Base64.getEncoder().encodeToString(originalInput.getBytes());

Обратите внимание, как мы получаем полный API кодировщика с помощью простого служебного методаgetEncoder().

Теперь вернем эту строку к исходной форме:

byte[] decodedBytes = Base64.getDecoder().decode(encodedString);
String decodedString = new String(decodedBytes);

2.2. Кодировка Java 8 Base64 без заполнения

В кодировке Base64 длина выходной кодированной строки должна быть кратна 3. Если это не так, выходные данные будут дополнены дополнительными символами заполнения (=).

При декодировании эти дополнительные символы заполнения будут отброшены. Чтобы глубже изучить отступы в Base64, посмотритеthis detailed answer over on StackOverflow.

Если вам нужноskip the padding of the output - возможно, потому что результирующая строка никогда не будет декодирована обратно - вы можете просто выбратьencode without padding:

String encodedString =
  Base64.getEncoder().withoutPadding().encodeToString(originalInput.getBytes());

2.3. Кодирование URL-адресов Java 8

Кодировка URL очень похожа на базовый кодер, который мы рассмотрели выше. Он использует URL-адрес и имя файла безопасного алфавита Base64 и не добавляет разделения строк:

String originalUrl = "https://www.google.co.nz/?gfe_rd=cr&ei=dzbFV&gws_rd=ssl#q=java";
String encodedUrl = Base64.getUrlEncoder().encodeToString(originalURL.getBytes());

Декодирование происходит примерно так же - служебный методgetUrlDecoder() возвращаетjava.util.Base64.Decoder, который затем используется для декодирования URL:

byte[] decodedBytes = Base64.getUrlDecoder().decode(encodedUrl);
String decodedUrl = new String(decodedBytes);

2.4. Кодирование MIME в Java 8

Начнем с генерации базового ввода MIME для кодирования:

private static StringBuilder getMimeBuffer() {
    StringBuilder buffer = new StringBuilder();
    for (int count = 0; count < 10; ++count) {
        buffer.append(UUID.randomUUID().toString());
    }
    return buffer;
}

Кодировщик MIME генерирует выходные данные в кодировке Base64, используя базовый алфавит, но в формате, удобном для MIME: каждая строка вывода не длиннее 76 символов и заканчивается возвратом каретки, за которым следует перевод строки ( ):

StringBuilder buffer = getMimeBuffer();
byte[] encodedAsBytes = buffer.toString().getBytes();
String encodedMime = Base64.getMimeEncoder().encodeToString(encodedAsBytes);

Служебный методgetMimeDecoder() возвращаетjava.util.Base64.Decoder, который затем используется в процессе декодирования:

byte[] decodedBytes = Base64.getMimeDecoder().decode(encodedMime);
String decodedMime = new String(decodedBytes);

3. Encoding/Decoding Using Apache Commons Code

Во-первых, нам нужно определить зависимость общего кодека вpom.xml:


    commons-codec
    commons-codec
    1.10

Обратите внимание, что вы можете проверить, были ли выпущены более новые версии библиотеки наMaven central.

Основным API является классorg.apache.commons.codec.binary.Base64, который можно параметризовать с помощью различных конструкторов:

  • Base64(boolean urlSafe) - создает API Base64, управляя безопасным для URL-адресов режимом - включен или выключен.

  • Base64 (int lineLength) - создает API Base64 в небезопасном режиме URL и контролирует длину строки (dпо умолчанию 76)

  • ”)

На Base64 API созданы, и кодирование и декодирование довольно просты:

String originalInput = "test input";
Base64 base64 = new Base64();
String encodedString = new String(base64.encode(originalInput.getBytes()));

Методdecode() классаBase64 возвращает декодированную строку:

String decodedString = new String(base64.decode(encodedString.getBytes()));

Другой простой вариант -using the static API of Base64 вместо создания экземпляра:

String originalInput = "test input";
String encodedString = new String(Base64.encodeBase64(originalInput.getBytes()));
String decodedString = new String(Base64.decodeBase64(encodedString.getBytes()));

4. ПреобразованиеString в массивbyte

Иногда нам нужно преобразоватьString вbyte[]. Самый простой способ сделать это - использовать методStringgetBytes():

String originalInput = "test input";
byte[] result = originalInput.getBytes();

assertEquals(originalInput.length(), result.length);

Лучше также предоставить кодировку и не зависеть от кодировки по умолчанию, поскольку она зависит от системы:

String originalInput = "test input";
byte[] result = originalInput.getBytes(StandardCharsets.UTF_16);

assertTrue(originalInput.length() < result.length);

Если наша строка закодированаBase64, мы можем использовать декодерthe Base64:

String originalInput = "dGVzdCBpbnB1dA==";
byte[] result = Base64.getDecoder().decode(originalInput);

assertEquals("test input", new String(result));

Мы также можем использовать методDatatypeConverter parseBase64Binary():

String originalInput = "dGVzdCBpbnB1dA==";
byte[] result = DatatypeConverter.parseBase64Binary(originalInput);

assertEquals("test input", new String(result));

Наконец, мы можем преобразовать шестнадцатеричныйString вbyte[], используя методDatatypeConverter:

String originalInput = "7465737420696E707574";
byte[] result = DatatypeConverter.parseHexBinary(originalInput);

assertEquals("test input", new String(result));

5. Заключение

В этой статье объясняются основы того, как выполнять кодирование и декодирование Base64 в Java с использованием новых API, представленных в Java 8, а также Apache Commons.

Наконец, есть несколько других API, которые стоит упомянуть для обеспечения аналогичной функциональности - например,java.xml.bind.DataTypeConverter сprintHexBinary иparseBase64Binary.

Фрагменты кода можно найтиover on GitHub.