Java8からものすごい今更追加されるBase64Encode/Decodeを扱うためのクラスをちょっと試してみたよ。
JDKのバージョンは、「8 Build b129」です。
Java8のBase64クラスの使いかた
Encoder/Decoderの取得
- Basic
RFC4648の標準Base64エンコーディングに基づく変換を行う。
Encoder encoder = Base64.getEncoder();
Decoder decoder = Base64.getDecoder();
- URL and Filename safe
RFC4648のbase64urlエンコーディングに基づく変換を行う。
Encoder encoder = Base64.getUrlEncoder();
Decoder decoder = Base64.getUrlDecoder();
- MIME
RFC2045のBase64エンコーディングに基づく変換を行う。
デフォルトで76文字ごとにCR+LFの改行文字が挿入される。
1行の長さ、および改行文字を指定したEncoderが取得できる。
Encoder encoder = Base64.getMimeEncoder();
encoder = Base64.getMimeEncoder(80, new byte[]{'\n'});
Decoder decoder = Base64.getMimeDecoder();
CommonsCodecとの比較
エンコード結果が微妙に違うっぽいのでまとめておきます。
import static java.util.Base64.*;
import static org.apache.commons.codec.binary.Base64.*;
:
:
:
Path path = Paths.get("./test.jpg");
byte[] bytes = Files.readAllBytes(path);
byte[] java8BasicEncoded = getEncoder().encode(bytes);
byte[] java8UrlEncoded = getUrlEncoder().encode(bytes);
byte[] java8MimeEncoded = getMimeEncoder().encode(bytes);
byte[] commonBasicEncoded = encodeBase64(bytes);
byte[] commonsUrlEncoded = encodeBase64URLSafe(bytes);
byte[] commonsMimeEncoded = encodeBase64Chunked(bytes);
System.out.println(Arrays.equals(java8BasicEncoded, commonBasicEncoded)); // true
System.out.println(Arrays.equals(java8UrlEncoded, commonsUrlEncoded)); // false
System.out.println(Arrays.equals(java8MimeEncoded, commonsMimeEncoded)); // false
base64urlエンコード
Java8のUrlEncoderの場合、パディングあり。
CommonsCodecのencodeBase64URLSafeの場合、パディングなし。Mimeエンコード
Java8のMimeEncoderの場合、末尾の改行文字なし。
CommonsCodecのencodeBase64Chunkedの場合、末尾の改行文字あり。
Base64的にどちらが正しいのかっていうのまではわかんない……。
Java8のEncoderは withoutPadding()
でパディングなしのエンコーダが取得できるので、
base64urlエンコードについては、これを使えばCommonsCodecと同じ変換結果になります。
byte[] urlEncodeNoPad = getUrlEncoder().withoutPadding().encode(bytes);
System.out.println(Arrays.equals(urlEncodeNoPad, commonsUrlEncoded)); // true