Декодирование Base64 в Java — задача, к которой я обращаюсь практически каждый день: извлекаю секреты из переменных окружения Kubernetes, читаю бинарные пейлоады из REST API, инспектирую JWT-токены в ходе отладки. Встроенный класс java.util.Base64 (начиная с JDK 8) предоставляет три варианта декодера: getDecoder() для стандартного Base64, getUrlDecoder() для URL-безопасных входных данных и getMimeDecoder() для данных с переносами строк, таких как вложения электронной почты. Для быстрой одноразовой проверки без написания кода Base64-декодер ToolDeck обработает всё мгновенно прямо в браузере. Это руководство ориентировано на Java 8+ и охватывает все три декодера, потоковую обработку с wrap(InputStream), извлечение пейлоада JWT, декодирование файлов и ответов API, Apache Commons Codec как альтернативу и четыре ошибки, которые приводят к некорректному выводу в продакшне.
- ✓Base64.getDecoder().decode(s) — стандартный подход, встроен в java.util.Base64 начиная с JDK 8, зависимости не нужны.
- ✓Используйте getUrlDecoder() для JWT-токенов и OAuth-пейлоадов — они используют алфавит - и _, а не + и /.
- ✓getMimeDecoder() игнорирует переносы строк и пробелы, что делает его правильным выбором для вложений электронной почты и PEM-сертификатов.
- ✓decoder.wrap(InputStream) декодирует на лету для больших файлов, не загружая всё в память.
- ✓Базовый декодер работает в строгом режиме — завершающие переносы строк, пробелы или символы неправильного алфавита немедленно выбрасывают IllegalArgumentException.
Что такое декодирование Base64?
Кодирование Base64 преобразует бинарные данные в 64-символьное ASCII-представление, чтобы они могли безопасно передаваться через текстовые каналы — поля JSON, заголовки HTTP, документы XML, тела электронных писем. Декодирование выполняет обратное преобразование: каждые 4 символа Base64 преобразуются обратно в 3 исходных байта. Символ дополнения = в конце сигнализирует о том, сколько байт было добавлено для заполнения последней группы. Base64 — не шифрование: любой может его обратить. Его цель — безопасность передачи, а не конфиденциальность.
Типичные сценарии декодирования в Java: извлечение конфигурационных значений, переданных как переменные окружения в Base64, распаковка бинарного содержимого файлов из ответов облачных API, чтение PEM-кодированных сертификатов и инспекция пейлоадов JWT-токенов в процессе отладки.
ZGItcHJvZC51cy1lYXN0LTEuYW1hem9uYXdzLmNvbTo1NDMy
db-prod.us-east-1.amazonaws.com:5432
Base64.getDecoder().decode() — стандартный метод декодирования
Класс java.util.Base64 был добавлен в JDK 8 и заменил старый sun.misc.BASE64Decoder, на который все привыкли полагаться. Внешние зависимости не нужны — достаточно import java.util.Base64 и вызова Base64.getDecoder().decode(). Метод принимает String или byte[] и возвращает byte[] декодированных данных.
Минимальный рабочий пример
import java.util.Base64;
import java.nio.charset.StandardCharsets;
public class DecodeCredential {
public static void main(String[] args) {
// Kubernetes secret value, Base64-encoded
String encoded = "ZGItcHJvZC51cy1lYXN0LTEuYW1hem9uYXdzLmNvbTo1NDMy";
byte[] decodedBytes = Base64.getDecoder().decode(encoded);
String connectionString = new String(decodedBytes, StandardCharsets.UTF_8);
System.out.println(connectionString);
// db-prod.us-east-1.amazonaws.com:5432
}
}Всегда указывайте StandardCharsets.UTF_8 при создании строки. Конструктор new String(bytes) без аргументов использует кодировку платформы по умолчанию, которая различается между системами. На Windows-сервере с Cp1252 в качестве кодировки по умолчанию многобайтовые UTF-8 символы будут беззвучно искажаться.
Проверка обратного преобразования
import java.util.Base64;
import java.nio.charset.StandardCharsets;
public class RoundTrip {
public static void main(String[] args) {
String original = "redis://cache-prod.internal:6379/session-store";
String encoded = Base64.getEncoder().encodeToString(
original.getBytes(StandardCharsets.UTF_8)
);
System.out.println(encoded);
// cmVkaXM6Ly9jYWNoZS1wcm9kLmludGVybmFsOjYzNzkvc2Vzc2lvbi1zdG9yZQ==
byte[] decoded = Base64.getDecoder().decode(encoded);
String recovered = new String(decoded, StandardCharsets.UTF_8);
System.out.println(recovered.equals(original)); // true
}
}Декодирование в заранее выделенный буфер
Перегрузка с тремя аргументами decode(byte[] src, byte[] dst) записывает результат напрямую в буфер назначения и возвращает количество записанных байт. Это позволяет избежать лишнего выделения памяти на горячих путях выполнения:
import java.util.Base64;
public class DecodeToBuffer {
public static void main(String[] args) {
byte[] src = "eyJob3N0IjoiMTAuMC4xLjUwIiwicG9ydCI6ODQ0M30=".getBytes();
byte[] dst = new byte[1024]; // pre-allocated
int len = Base64.getDecoder().decode(src, dst);
String result = new String(dst, 0, len);
System.out.println(result);
// {"host":"10.0.1.50","port":8443}
}
}decode() выбрасывает IllegalArgumentException, если входные данные содержат символы вне алфавита Base64 (включая переносы строк и пробелы). Если входные данные могут содержать пробельные символы, переключитесь на getMimeDecoder() или очистите их с помощью encoded.strip() перед декодированием.Декодирование Base64 в нестандартные типы и пользовательские объекты
Сырой byte[], возвращаемый decode(), часто нужно преобразовать во что-то более конкретное: UUID, сериализованный Java-объект, protobuf-сообщение или метку времени. Сам декодер всегда возвращает байты — преобразование в доменные типы лежит на вашей ответственности.
Base64 в UUID
import java.util.Base64;
import java.nio.ByteBuffer;
import java.util.UUID;
public class DecodeUUID {
public static UUID fromBase64(String encoded) {
byte[] bytes = Base64.getUrlDecoder().decode(encoded);
ByteBuffer bb = ByteBuffer.wrap(bytes);
return new UUID(bb.getLong(), bb.getLong());
}
public static void main(String[] args) {
// Compact Base64-encoded UUID from an API response
String encoded = "f47ac10b-58cc-4372-a567-0e02b2c3d479";
UUID original = UUID.fromString(encoded);
// Encode to Base64 (compact form — 22 chars vs 36)
ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
bb.putLong(original.getMostSignificantBits());
bb.putLong(original.getLeastSignificantBits());
String compact = Base64.getUrlEncoder().withoutPadding()
.encodeToString(bb.array());
System.out.println(compact); // 9HrBC1jMQ3KlZw4CssPUeQ
// Decode back
UUID recovered = fromBase64(compact);
System.out.println(recovered); // f47ac10b-58cc-4372-a567-0e02b2c3d479
}
}Base64 в десериализованный JSON-объект с Jackson
import java.util.Base64;
import java.nio.charset.StandardCharsets;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.Instant;
public class DecodeJsonPayload {
record DeployEvent(String service, String region, Instant deployedAt, int replicas) {}
public static void main(String[] args) throws Exception {
// Base64-encoded JSON payload from a message queue
String encoded = "eyJzZXJ2aWNlIjoicGF5bWVudC1nYXRld2F5Iiwi"
+ "cmVnaW9uIjoiZXUtd2VzdC0xIiwiZGVwbG95ZWRBdCI6"
+ "IjIwMjYtMDMtMTVUMTQ6MzA6MDBaIiwicmVwbGljYXMiOjR9";
byte[] jsonBytes = Base64.getDecoder().decode(encoded);
String json = new String(jsonBytes, StandardCharsets.UTF_8);
System.out.println(json);
// {"service":"payment-gateway","region":"eu-west-1",
// "deployedAt":"2026-03-15T14:30:00Z","replicas":4}
ObjectMapper mapper = new ObjectMapper();
mapper.findAndRegisterModules(); // picks up JavaTimeModule
DeployEvent event = mapper.readValue(jsonBytes, DeployEvent.class);
System.out.println(event.service()); // payment-gateway
System.out.println(event.deployedAt()); // 2026-03-15T14:30:00Z
}
}ObjectInputStream для десериализации ненадёжных данных Base64. Атаки через механизм десериализации Java хорошо задокументированы — если закодированный контент поступает из внешнего источника, разбирайте его как JSON или protobuf вместо использования нативной Java-сериализации.Справочник методов Base64.Decoder
Все методы принадлежат java.util.Base64 и его внутреннему классу Base64.Decoder. Три фабричных метода Base64 возвращают разные экземпляры декодера; методы decode() и wrap() находятся на экземпляре Decoder.
getMimeDecoder() — декодирование MIME и данных с переносами строк
Базовый декодер отклоняет всё, что выходит за пределы алфавита Base64 — в том числе переносы строк \r\n, которые всегда присутствуют в MIME-контенте. Вложения электронной почты, PEM-сертификаты и некоторые старые API-ответы переносят вывод Base64 каждые 76 символов. getMimeDecoder() беззвучно игнорирует разделители строк и любые символы вне алфавита Base64, обрабатывая это из коробки.
import java.util.Base64;
import java.nio.charset.StandardCharsets;
public class MimeDecode {
public static void main(String[] args) {
// PEM certificate body — line-wrapped at 76 characters
String pemBody = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t\r\n"
+ "TUlJQm96Q0NBVWlnQXdJQkFnSUpBSXBhVDJU\r\n"
+ "aVFvZU1BMEdDU3FHU0liM0RRRU==";
// getDecoder() would throw IllegalArgumentException here
byte[] decoded = Base64.getMimeDecoder().decode(pemBody);
System.out.println(new String(decoded, StandardCharsets.UTF_8));
// -----BEGIN CERTIFICATE-----
// MIIBozCCAUigAwIBAgIJAIpaT2T...
}
}getMimeDecoder() работает в мягком режиме: он пропускает недопустимые символы вместо того, чтобы выбрасывать исключение. Для известных MIME-данных это нормально, но при произвольных входных данных он может беззвучно проглотить повреждение. Используйте getDecoder(), когда нужна строгая проверка.Декодирование Base64 из файла и ответа API
Чтение файла в кодировке Base64 с диска
Бинарные файлы (изображения, сертификаты, зашифрованные блобы) иногда хранятся на диске в виде текста Base64. Прочитайте файл, декодируйте его и запишите бинарный результат:
import java.util.Base64;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class DecodeFile {
public static void main(String[] args) {
Path inputPath = Path.of("tls-cert.pem.b64");
Path outputPath = Path.of("tls-cert.pem");
try {
String encoded = Files.readString(inputPath).strip();
byte[] decoded = Base64.getMimeDecoder().decode(encoded);
Files.write(outputPath, decoded);
System.out.printf("Decoded %d bytes → %s%n", decoded.length, outputPath);
} catch (IOException e) {
System.err.println("File error: " + e.getMessage());
} catch (IllegalArgumentException e) {
System.err.println("Invalid Base64: " + e.getMessage());
}
}
}Декодирование поля Base64 из ответа HTTP API
Облачные API (AWS KMS, GitHub Contents, Vault) часто возвращают бинарные данные в виде строк Base64 внутри JSON. Сначала разберите JSON, затем декодируйте нужное поле:
import java.util.Base64;
import java.nio.charset.StandardCharsets;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class DecodeApiResponse {
public static void main(String[] args) {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/secrets/db-password"))
.header("Authorization", "Bearer sk-prod-9f8e7d6c")
.build();
try {
HttpResponse<String> response = client.send(
request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
System.err.printf("Unexpected status: %d%n", response.statusCode());
return;
}
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(response.body());
// API returns: {"name":"db-password","value":"cG9zdGdyZXM6eGs5...","version":3}
String encodedValue = root.get("value").asText();
byte[] decoded = Base64.getDecoder().decode(encodedValue);
String secret = new String(decoded, StandardCharsets.UTF_8);
System.out.println("Secret: " + secret);
// Secret: postgres:xk9mP2qR@db-prod:5432/orders
} catch (Exception e) {
System.err.println("Failed to fetch secret: " + e.getMessage());
}
}
}IllegalArgumentException отдельно от сетевых ошибок. Смешение исключений ввода-вывода с ошибками декодирования усложняет отладку — вам нужно сразу понимать, вернул ли API некорректные данные или произошёл сетевой сбой.Декодирование Base64 из командной строки
Не всегда нужна Java-программа. В любой системе Linux и macOS есть команда base64, а JDK 9+ поставляется с jshell для интерактивных однострочников на Java. При быстрой проверке в процессе отладки это быстрее, чем компилировать класс.
# Decode a Base64 string (Linux / macOS)
echo "eyJob3N0IjoiMTAuMC4xLjUwIiwicG9ydCI6ODQ0M30=" | base64 --decode
# {"host":"10.0.1.50","port":8443}
# Decode and pretty-print with jq
echo "eyJob3N0IjoiMTAuMC4xLjUwIiwicG9ydCI6ODQ0M30=" | base64 --decode | jq .
# {
# "host": "10.0.1.50",
# "port": 8443
# }
# Quick decode with jshell (JDK 9+)
echo 'System.out.println(new String(java.util.Base64.getDecoder().decode("c2VydmVyLWNvbmZpZw==")))' | jshell -
# server-config
# macOS uses -D instead of --decode
echo "c2VydmVyLWNvbmZpZw==" | base64 -DДля вставки закодированных строк прямо в браузер Base64-декодер ToolDeck поддерживает как стандартный, так и URL-безопасный варианты без какой-либо настройки.
Высокопроизводительная альтернатива: Apache Commons Codec
Встроенный java.util.Base64 уже хорошо оптимизирован — JDK 11+ использует интринсики x86 для кодирования и декодирования. Для большинства приложений нет причин тянуться к сторонней библиотеке. Тем не менее Apache Commons Codec остаётся популярным в унаследованных кодовых базах и предлагает Base64InputStream для потокового декодирования с автоматической обработкой пробельных символов.
<!-- pom.xml -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.17.0</version>
</dependency>import org.apache.commons.codec.binary.Base64;
public class CommonsCodecDecode {
public static void main(String[] args) {
// Commons Codec is more lenient — handles whitespace and line breaks
String encoded = "eyJob3N0IjoiMTAuMC4xLjUw\nIiwicG9ydCI6ODQ0M30=";
byte[] decoded = Base64.decodeBase64(encoded);
System.out.println(new String(decoded));
// {"host":"10.0.1.50","port":8443}
}
}Главное преимущество Commons Codec перед встроенным API — мягкое отношение к пробельным символам по умолчанию и класс Base64InputStream, появившийся раньше decoder.wrap() из Java. Если вы используете Java 8+, встроенный API покрывает всё, что умеет Commons Codec. Я обращаюсь к Commons Codec только когда проект уже от него зависит.
Потоковая обработка больших файлов Base64 с decoder.wrap()
Загрузка файла Base64 размером 200 МБ через Files.readString() с последующим вызовом decode() выделяет около 350 МБ кучи: закодированная строка плюс декодированный массив байт. decoder.wrap(InputStream) декодирует на лету, сохраняя постоянное использование памяти.
import java.util.Base64;
import java.io.*;
import java.nio.file.*;
public class StreamDecode {
public static void main(String[] args) throws IOException {
Path src = Path.of("database-dump.sql.b64");
Path dst = Path.of("database-dump.sql");
try (InputStream in = Base64.getMimeDecoder().wrap(
new BufferedInputStream(Files.newInputStream(src)));
OutputStream out = new BufferedOutputStream(Files.newOutputStream(dst))) {
byte[] buffer = new byte[8192];
int bytesRead;
long total = 0;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
total += bytesRead;
}
System.out.printf("Decoded %d bytes → %s%n", total, dst);
}
}
}В Java 9+ можно заменить цикл чтения на in.transferTo(out) — то же самое с меньшим количеством кода. Используйте getMimeDecoder().wrap() вместо getDecoder().wrap(), если файл может содержать переносы строк (PEM-файлы, экспорты почты).
import java.util.Base64;
import java.io.*;
import java.nio.file.*;
public class StreamDecodeSimple {
public static void main(String[] args) throws IOException {
try (InputStream in = Base64.getMimeDecoder().wrap(
new BufferedInputStream(Files.newInputStream(Path.of("backup.tar.b64"))));
OutputStream out = Files.newOutputStream(Path.of("backup.tar"))) {
in.transferTo(out); // Java 9+
}
}
}getDecoder().wrap() не допускает переносов строк в потоке. Если данные Base64 содержат символы новой строки (перенос через каждые 76 символов), используйте getMimeDecoder().wrap() — иначе поток беззвучно производит повреждённый вывод или выбрасывает исключение в непредсказуемой позиции чтения.Декодирование пейлоада JWT в Java без JWT-библиотеки
JWT состоит из трёх сегментов, закодированных в Base64url и разделённых точками. Средний сегмент — это пейлоад, который вас интересует при отладке. Его можно декодировать без подключения jjwt или Nimbus. Разбейте токен по ., декодируйте вторую часть с помощью getUrlDecoder() и разберите полученный JSON:
import java.util.Base64;
import java.nio.charset.StandardCharsets;
public class JWTInspect {
public static String decodeJwtPayload(String token) {
String[] parts = token.split("\\.");
if (parts.length != 3) {
throw new IllegalArgumentException(
"Invalid JWT: expected 3 segments, got " + parts.length);
}
// JWT uses URL-safe Base64 without padding
byte[] payload = Base64.getUrlDecoder().decode(parts[1]);
return new String(payload, StandardCharsets.UTF_8);
}
public static void main(String[] args) {
String token = "eyJhbGciOiJSUzI1NiJ9"
+ ".eyJzdWIiOiJ1c3ItNjcyIiwiaXNzIjoiYXV0aC5leGFtcGxlLmNvbSIs"
+ "ImV4cCI6MTc0MTk1NjgwMCwicm9sZXMiOlsiYWRtaW4iLCJiaWxsaW5nIl19"
+ ".SIGNATURE_PLACEHOLDER";
String payload = decodeJwtPayload(token);
System.out.println(payload);
// {"sub":"usr-672","iss":"auth.example.com",
// "exp":1741956800,"roles":["admin","billing"]}
}
}Распространённые ошибки
Я сталкивался с каждой из них на ревью кода, и первые две составляют подавляющее большинство связанных с Base64 ошибок в продакшн-сервисах на Java.
Проблема: JWT-токены и токены доступа OAuth используют URL-безопасный алфавит (- и _). Передача их в getDecoder() выбрасывает IllegalArgumentException, поскольку - отсутствует в стандартном алфавите Base64.
Решение: Проверьте источник данных: токены из систем аутентификации требуют getUrlDecoder(); MIME-вложения требуют getMimeDecoder().
// JWT header — URL-safe, no padding String header = "eyJhbGciOiJSUzI1NiJ9"; byte[] decoded = Base64.getDecoder().decode(header); // IllegalArgumentException: Illegal base64 character 2d
String header = "eyJhbGciOiJSUzI1NiJ9";
byte[] decoded = Base64.getUrlDecoder().decode(header);
System.out.println(new String(decoded));
// {"alg":"RS256"}Проблема: new String(bytes) использует кодировку JVM по умолчанию, которая различается между окружениями. Linux CI-сервер (UTF-8) и Windows production-хост (Cp1252) дают разные результаты для одних и тех же байт.
Решение: Всегда передавайте StandardCharsets.UTF_8 вторым аргументом.
byte[] decoded = Base64.getDecoder().decode(encoded); String result = new String(decoded); // platform-dependent — may corrupt multi-byte characters
byte[] decoded = Base64.getDecoder().decode(encoded); String result = new String(decoded, StandardCharsets.UTF_8); // consistent across all platforms
Проблема: Строки Base64, скопированные из терминала или прочитанные из конфигурационных файлов, часто имеют завершающие переносы строк. Базовый декодер отклоняет любой символ вне алфавита Base64.
Решение: Вызовите .strip() для входных данных перед декодированием или переключитесь на getMimeDecoder(), который игнорирует пробельные символы.
// Read from environment variable — has a trailing newline
String encoded = System.getenv("DB_PASSWORD_B64"); // "cG9zdGdyZXM=
"
byte[] decoded = Base64.getDecoder().decode(encoded);
// IllegalArgumentException: Illegal base64 character aString encoded = System.getenv("DB_PASSWORD_B64");
byte[] decoded = Base64.getDecoder().decode(encoded.strip());
System.out.println(new String(decoded, StandardCharsets.UTF_8));
// postgresПроблема: Вызов new String(decoded) для бинарного контента (изображения, protobuf, зашифрованные блобы) создаёт некорректную строку. Обратное преобразование в байты впоследствии беззвучно повреждает данные, поскольку конструктор String заменяет недопустимые UTF-8 последовательности.
Решение: Сохраняйте бинарные данные как byte[] на протяжении всего пайплайна. Преобразуйте в String только когда точно знаете, что контент является текстом.
byte[] decoded = Base64.getDecoder().decode(pngBase64);
String imageStr = new String(decoded); // corrupts binary
Files.writeString(Path.of("image.png"), imageStr); // broken filebyte[] decoded = Base64.getDecoder().decode(pngBase64);
// Write bytes directly — no String conversion
Files.write(Path.of("image.png"), decoded);Сравнение методов
Встроенные декодеры покрывают большинство случаев. Apache Commons Codec и Guava — альтернативы, которые можно встретить в более старых кодовых базах.
Для JWT-токенов и современных API-пейлоадов: getUrlDecoder(). Для вложений электронной почты и PEM-сертификатов: getMimeDecoder(). Для больших файлов, где важна память: decoder.wrap(InputStream). Для всего остального: getDecoder(). Apache Commons Codec имеет смысл только если он уже есть в дереве зависимостей.
Для быстрой проверки в процессе разработки онлайн-декодер Base64 быстрее, чем писать одноразовый класс.
Часто задаваемые вопросы
Как декодировать строку Base64 в Java?
Импортируйте java.util.Base64 и вызовите Base64.getDecoder().decode(encodedString). Метод возвращает byte[] — оберните результат в new String(bytes, StandardCharsets.UTF_8), чтобы получить читаемый текст. Для URL-безопасного Base64 (используется в JWT) замените getDecoder() на getUrlDecoder().
import java.util.Base64;
import java.nio.charset.StandardCharsets;
byte[] decoded = Base64.getDecoder().decode("c2VydmVyLWNvbmZpZw==");
String result = new String(decoded, StandardCharsets.UTF_8);
System.out.println(result); // server-configВ чём разница между getDecoder() и getMimeDecoder() в Java?
getDecoder() работает в строгом режиме — он отклоняет любой символ вне алфавита Base64, включая переносы строк. getMimeDecoder() допускает разделители строк (\r\n) и игнорирует любые символы, не входящие в Base64, что делает его правильным выбором для декодирования вложений электронной почты и PEM-сертификатов, в которых данные переносятся каждые 76 символов.
String wrapped = "c2VydmVyLWNv\r\nbmZpZw=="; // getDecoder() throws IllegalArgumentException // Base64.getDecoder().decode(wrapped); // FAILS // getMimeDecoder() handles it byte[] decoded = Base64.getMimeDecoder().decode(wrapped); System.out.println(new String(decoded)); // server-config
Как декодировать URL-безопасную строку Base64 в Java?
Используйте Base64.getUrlDecoder().decode(encoded). URL-декодер ожидает алфавит - и _, определённый в RFC 4648 §5, а не + и /. Токены JWT всегда используют этот алфавит. Если символы дополнения (=) были удалены (стандартная практика в JWT), URL-декодер всё равно справится — он принимает как дополненные, так и недополненные входные данные.
import java.util.Base64;
// JWT header — URL-safe, no padding
String jwtHeader = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9";
byte[] decoded = Base64.getUrlDecoder().decode(jwtHeader);
System.out.println(new String(decoded));
// {"alg":"HS256","typ":"JWT"}Как потоково декодировать большой файл Base64 в Java?
Используйте decoder.wrap(inputStream), обернув FileInputStream. Возвращаемый InputStream декодирует Base64 на лету по мере чтения байт, поэтому использование памяти остаётся постоянным независимо от размера файла. Пропустите его через BufferedInputStream или сразу в Files.copy() для максимальной производительности.
import java.util.Base64;
import java.io.*;
import java.nio.file.*;
try (InputStream in = Base64.getDecoder().wrap(
new BufferedInputStream(new FileInputStream("payload.b64")));
OutputStream out = new FileOutputStream("payload.bin")) {
in.transferTo(out);
}Почему Base64.getDecoder().decode() выбрасывает IllegalArgumentException?
Базовый декодер работает в строгом режиме: он отклоняет переносы строк, пробелы и любой символ вне диапазона A-Za-z0-9+/=. Три распространённые причины: у входной строки есть завершающий перенос строки (обрежьте его), строка использует URL-безопасные символы - и _ (переключитесь на getUrlDecoder()), или строка переносится каждые 76 символов (переключитесь на getMimeDecoder()). Если сообщение об ошибке непонятно, проверьте сырые байты.
String raw = "c2VydmVyLWNvbmZpZw==\n"; // trailing newline // Option 1: trim whitespace byte[] decoded = Base64.getDecoder().decode(raw.strip()); // Option 2: use MIME decoder which ignores whitespace byte[] decoded2 = Base64.getMimeDecoder().decode(raw);
Можно ли декодировать Base64 в Java без java.util.Base64?
Да, но на Java 8+ нет никаких причин это делать. До Java 8 разработчики использовали sun.misc.BASE64Decoder (внутренний, удалён в Java 9+), javax.xml.bind.DatatypeConverter.parseBase64Binary() (удалён в Java 11) или Apache Commons Codec. Все три варианта либо устарели, либо требуют дополнительной зависимости. Используйте java.util.Base64 — он быстрее, входит в состав JDK и охватывает все три варианта (базовый, URL-безопасный, MIME).
Связанные инструменты
- Base64 Encoder — кодируйте текст или бинарные данные в Base64 прямо в браузере, удобно для генерации тестовых данных для вставки в юнит-тесты на Java.
- JWT Decoder — разбивает и декодирует все три сегмента JWT сразу, с пошаговой инспекцией полей пейлоада — быстрее, чем писать Java-класс, когда нужно просто прочитать токен.
- URL Decoder — декодирует percent-encoded строки, полезно когда ответы API сочетают данные Base64url с percent-encoded параметрами запроса.
- JSON Formatter — после декодирования пейлоада JWT в Base64 или конфига API вставьте JSON сюда, чтобы красиво отформатировать и проверить структуру.