Декодування 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 перетворює бінарні дані на ASCII-представлення з 64 символів, щоб вони могли безпечно передаватися через текстові канали — поля 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 з переносами рядків
Базовий декодер відхиляє все, що виходить за межі алфавіту 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 у Java вже добре оптимізований — 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()
Завантаження 200 МБ Base64-файлу через 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() — інакше потік мовчки виробляє пошкоджений вивід або кидає виняток у непередбачуваній позиції читання.Декодування Base64 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-продакшн-хост (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. Зворотне перетворення у байти пізніше тихо пошкоджує дані, оскільки конструктор 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() кидає IllegalArgumentException // Base64.getDecoder().decode(wrapped); // FAILS // getMimeDecoder() обробляє коректно 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-декодер все одно справляється — Java-декодер приймає як доповнений, так і недоповнений вхід.
import java.util.Base64;
// JWT-заголовок — URL-безпечний, без доповнення
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"; // завершальний символ нового рядка // Варіант 1: обрізати пробіли byte[] decoded = Base64.getDecoder().decode(raw.strip()); // Варіант 2: використати MIME-декодер, який ігнорує пробіли 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-кодуванням; корисно, коли відповіді API поєднують Base64url-дані з percent-кодованими параметрами запиту.
- JSON Formatter — після декодування Base64 JWT-пейлоада або конфігурації API вставте JSON сюди для форматування і перевірки структури.