1. 概要

このチュートリアルでは、JavaでBase64のエンコードおよびデコード機能を提供するさまざまなユーティリティについて説明します。

主に、新しいJava8APIについて説明します。 また、ApacheCommonsのユーティリティAPIを使用します。

2. Base64用のJava8

Java 8は、 java.util.Base64 ユーティリティクラスを介して、Base64機能を標準APIに追加しました。

基本的なエンコーダプロセスを見てみましょう。

2.1. Java 8 Basic Base64

基本的なエンコーダーは、物事をシンプルに保ち、行を区切ることなく、入力をそのままエンコードします。

エンコーダーは、入力を A-Za-z0-9 +/文字セットの文字セットにマップします。 したがって、デコーダーはこのセット以外の文字を拒否します。

まず、単純な文字列エンコードしましょう。

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

単純なgetEncoder()ユーティリティメソッドを介して完全なエンコーダAPIを取得する方法に注意してください。

そのStringをデコードして元の形式に戻しましょう。

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

2.2. パディングなしのJava8Base64エンコーディング

Base64エンコードでは、出力エンコードされたStringの長さは3の倍数である必要があります。 エンコーダーは、この要件を満たすために、必要に応じて出力の最後に1つまたは2つのパディング文字( = )を追加します。

デコード時に、デコーダーはこれらの余分なパディング文字を破棄します。 Base64のパディングをさらに深く掘り下げるには、 StackOverflowに関するこの詳細な回答を確認してください。

場合によっては、出力のパディングをスキップする必要があります。 たとえば、結果のStringはデコードされません。 したがって、パディングなしでエンコードするを選択するだけです。

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

2.3. Java8URLエンコーディング

URLエンコードは、基本的なエンコーダーと非常によく似ています。 また、URLとファイル名SafeBase64アルファベットを使用します。 さらに、行の区切りは追加されません。

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. Java8MIMEエンコーディング

エンコードするための基本的な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文字以内です。 また、キャリッジリターンとそれに続く改行( \ r \ n )で終了します。

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

デコードプロセスでは、 java.util.Base64.Decoderを返すgetMimeDecoder()メソッドを使用できます。

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

3. ApacheCommonsコードを使用したエンコード/デコード

まず、pom.xmlcommons-codec依存関係を定義する必要があります。

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.15</version>
</dependency>

メインのAPIは、org.apache.commons.codec.binary.Base64クラスです。 さまざまなコンストラクターで初期化できます。

  • Base64(boolean urlSafe)は、URLセーフモード(オンまたはオフ)を制御することにより、Base64APIを作成します。
  • Base64(int lineLength)は、URL非安全モードでBase64 APIを作成し、行の長さを制御します(デフォルトは76)。
  • Base64(int lineLength、byte [] lineSeparator)は、追加の行区切り文字(デフォルトではCRLF( “\ r \ n”))を受け入れることにより、Base64APIを作成します。

Base64 APIが作成されると、エンコードとデコードの両方が非常に簡単になります。

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

さらに、 Base64クラスのdecode()メソッドは、デコードされた文字列を返します。

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

別のオプションは、インスタンスを作成する代わりに、Base64の静的APIを使用することです。

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

4. 文字列バイト配列に変換する

Stringbyte[]に変換する必要がある場合があります。 最も簡単な方法は、 String getBytes()メソッドを使用することです。

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でエンコードされている場合、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));

最後に、DatatypeConverter.parseHexBinaryメソッドを使用して、16進文字列をbyte[]に変換できます。

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

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

5. 結論

この記事では、JavaでBase64のエンコードとデコードを行う方法の基本について説明しました。 Java8とApacheCommonsで導入された新しいAPIを使用しました。

最後に、同様の機能を提供する他のAPIがいくつかあります。java.xml.bind.DataTypeConverterprintHexBinaryおよびparseBase64Binary

コードスニペットは、GitHubにあります。