Java での Base64 デコードは、数日おきに必要になる作業です — Kubernetes の環境変数からシークレットを取り出したり、REST API からバイナリペイロードを読み取ったり、デバッグ中に JWT トークンを検査したりするときに使います。Java の組み込みクラス java.util.Base64(JDK 8 以降)は 3 種類のデコーダーを提供しています:標準 Base64 用の getDecoder()、URL セーフ入力用の getUrlDecoder()、メール添付ファイルのような行折り返しデータ用の getMimeDecoder() です。 コードを書かずにすぐ確認したい場合は、 ToolDeck の Base64 デコーダー をブラウザで即座に使えます。このガイドは Java 8 以降を対象とし、3 種類のデコーダーすべて、wrap(InputStream) によるストリーミング、JWT ペイロードの抽出、ファイルおよび API レスポンスのデコード、代替手段としての Apache Commons Codec、そして本番環境で壊れた出力を生む 4 つのよくあるミスを解説します。
- ✓Base64.getDecoder().decode(s) が標準的な方法です — JDK 8 から java.util.Base64 に組み込まれており、依存関係は不要です。
- ✓JWT トークンや OAuth ペイロードには getUrlDecoder() を使います — + と / ではなく - と _ のアルファベットを使用しています。
- ✓getMimeDecoder() は改行と空白を無視するため、メール添付ファイルや PEM 証明書に最適です。
- ✓decoder.wrap(InputStream) は大きなファイルをすべてメモリに読み込まずにオンザフライでデコードします。
- ✓基本デコーダーは厳格です — 末尾の改行、スペース、または誤ったアルファベット文字があると即座に IllegalArgumentException をスローします。
Base64 デコードとは?
Base64 エンコードは、バイナリデータをテキストのみのチャネル(JSON フィールド、HTTP ヘッダー、XML ドキュメント、メール本文)を安全に通過できるよう、64 文字の ASCII 表現に変換します。デコードはこれを逆転させます。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
}
}String を構築する際は必ず StandardCharsets.UTF_8 を指定してください。 引数なしの new String(bytes) コンストラクターはプラットフォームのデフォルトエンコーディングを使用し、システムによって異なります。デフォルトが Cp1252 の Windows サーバーでは、マルチバイト 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
}
}事前確保バッファへのデコード
3 引数の 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() は、入力に Base64 アルファベット外の文字(改行やスペースを含む)が含まれている場合、IllegalArgumentException をスローします。 入力に空白が含まれる可能性がある場合は、getMimeDecoder() に切り替えるか、デコード前に encoded.strip() で除去してください。非標準型とカスタムオブジェクトへの Base64 デコード
decode() から返された生の byte[] は、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 から Jackson で JSON オブジェクトにデシリアライズ
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 を使わないでください。Java のデシリアライズ攻撃はよく知られています — エンコードされたコンテンツが外部ソースから来る場合は、ネイティブ Java シリアライゼーションではなく JSON または protobuf としてパースしてください。Base64.Decoder メソッドリファレンス
すべてのメソッドは java.util.Base64 とその内部クラス Base64.Decoder に属しています。Base64 の 3 つのファクトリーメソッドは異なるデコーダーインスタンスを返し、decode() と wrap() メソッドは Decoder インスタンスにあります。
getMimeDecoder() — 行折り返しと MIME Base64 のデコード
基本デコーダーは Base64 アルファベット以外のものをすべて拒否します — MIME エンコードされたコンテンツが必ず含む \r\n 改行も例外ではありません。 メール添付ファイル、PEM 証明書、一部の古い API レスポンスは Base64 出力を 1 行 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() を使用してください。ファイルと API レスポンスからの Base64 デコード
ディスクから Base64 エンコードされたファイルを読み込む
バイナリファイル(画像、証明書、暗号化された blob)がディスク上に 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());
}
}
}HTTP API レスポンスの Base64 フィールドをデコード
クラウド API(AWS KMS、GitHub Contents、Vault)は JSON 内の文字列として Base64 でバイナリデータを返すことがよくあります。まず 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 用に、ネットワークエラーとは別の try-catch でラップしてください。I/O 例外とデコード失敗を混在させるとデバッグが難しくなります — 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エンコードされた文字列をブラウザに直接貼り付けたい場合は、 ToolDeck の Base64 デコーダー が標準と URL セーフの両方のバリアントをセットアップなしで処理できます。
高性能な代替手段:Apache Commons Codec
Java の組み込み 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}
}
}組み込み API に対する Commons Codec の主な利点は、デフォルトで空白に対して寛容なことと、Java の decoder.wrap() より以前に存在していた Base64InputStream クラスです。Java 8 以降であれば、組み込み API が Commons Codec のすべてをカバーしています。Commons Codec に頼るのは、プロジェクトがすでにそれに依存している場合だけです。
decoder.wrap() による大きな Base64 ファイルのストリーミング
200 MB の Base64 ファイルを Files.readString() で読み込んで decode() を呼び出すと、エンコードされた文字列とデコードされたバイト配列で約 350 MB のヒープが確保されます。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 以降では、read ループを in.transferTo(out) で置き換えられます — 同じことをより少ないコードで実現できます。ファイルに改行が含まれる可能性がある場合(PEM ファイル、メールエクスポート)は、getDecoder().wrap() の代わりに getMimeDecoder().wrap() を使ってください。
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 ペイロードを Base64 デコード
JWT はドットで結合された 3 つの Base64url エンコードされたセグメントで構成されています。中間のセグメントがペイロードです — デバッグ時に確認したい部分です。jjwt や Nimbus を依存関係に追加しなくてもデコードできます。. で分割し、2 番目の部分を 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"]}
}
}よくあるミス
コードレビューでこれらのミスをすべて見てきました。最初の 2 つが Java サービスにおける Base64 関連の本番バグの大半を占めています。
問題: JWT トークンや OAuth アクセストークンは URL セーフアルファベット(- と _)を使用しています。それらを getDecoder() に渡すと、- が標準 Base64 アルファベットにないため IllegalArgumentException がスローされます。
解決策: データのソースを確認してください:認証システムからのトークンには 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)は同じバイト列に対して異なる結果を生成します。
解決策: 2 番目の引数として必ず 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問題: バイナリコンテンツ(画像、protobuf、暗号化された blob)に new String(decoded) を呼び出すと無効な 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 デコーダー の方が、ワンオフのクラスを書くより速いです。
よくある質問
Java で Base64 文字列をデコードするには?
java.util.Base64 をインポートして、Base64.getDecoder().decode(encodedString) を呼び出します。戻り値は byte[] です。読めるテキストにするには new String(bytes, StandardCharsets.UTF_8) でラップしてください。JWT など URL セーフ Base64 の場合は、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-configJava の getDecoder() と getMimeDecoder() の違いは?
getDecoder() は厳格で、改行を含む Base64 アルファベット以外の文字をすべて拒否します。getMimeDecoder() は行区切り文字(\r\n)を許容し、Base64 以外の文字を無視するため、データが 76 文字単位で折り返されているメール添付ファイルや PEM 証明書のデコードに適しています。
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
Java で Base64 URL セーフ文字列をデコードするには?
Base64.getUrlDecoder().decode(encoded) を使用します。URL デコーダーは + と / の代わりに RFC 4648 §5 で定義された - と _ のアルファベットを使用します。JWT トークンは常にこのアルファベットを使用します。パディング文字(=)が省略されている場合(JWT では一般的)でも、Java の 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"}Java で大きな Base64 ファイルをストリームデコードするには?
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+/= 以外のすべての文字を拒否します。よくある原因は 3 つあります:入力に末尾の改行がある(strip() で除去する)、入力が - や _ などの 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);
Java で java.util.Base64 を使わずに Base64 をデコードできますか?
できますが、Java 8+ では使わない理由がありません。Java 8 以前は、sun.misc.BASE64Decoder(内部 API、Java 9 以降削除)、javax.xml.bind.DatatypeConverter.parseBase64Binary()(Java 11 で削除)、Apache Commons Codec が使われていました。これらはいずれも非推奨か追加の依存関係が必要です。java.util.Base64 を使用してください。高速で JDK に同梱されており、3 つのバリアント(basic、URL セーフ、MIME)をすべてカバーしています。
関連ツール
- Base64 エンコーダー — テキストまたはバイナリデータをブラウザで Base64 にエンコードします。Java ユニットテストに貼り付けるテストフィクスチャの生成に便利です。
- JWT デコーダー — 3 つの JWT セグメントすべてを一度に分割してデコードし、フィールドごとのペイロード検査ができます — トークンを読むだけなら Java クラスを書くより速いです。
- URL デコーダー — URL エンコードされた文字列をパーセントデコードします。API レスポンスが Base64url データとパーセントエンコードされたクエリパラメーターを組み合わせている場合に役立ちます。
- JSON フォーマッター — Base64 JWT ペイロードや API 設定のデコード後、JSON をここに貼り付けてきれいに整形し、構造を検証できます。