Flavors of Base64 encoding

The Oracle documentation for java.util.Base64 refers to three different kinds of Base64, but only by reference to RFCs. Here it is in one place.

RFC 4648 Table 1: Normal base64

Both RFC 2045 “Multipurpose Internet Mail Extensions” (November 1996) and RFC 4648 Table 1 “The Base16, Base32, and Base64 Data Encodings” (October 2006) define this same alphabet:

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ padded with =

This is the alphabet used by Java’s Base64.getEncoder(), and also by Base64.getMimeEncoder(). The only difference is that getMimeEncoder also inserts \r\n every 76 characters, and ignores non-base64 characters (including any \r and \n) during decoding.

In Java, new String(Base64.getEncoder().encode("Hello??".getBytes())) should give you "SGVsbG8/Pw==".

In Kotlin, it’s String(Base64.getEncoder().encode("Hello??".toByteArray())).

RFC 4648 Table 2: URL-safe base64

RFC 4648 Table 2 “The Base16, Base32, and Base64 Data Encodings” (October 2006) defines this “URL- and filename-safe” alphabet:

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_ padded with =

This is the alphabet used by Java’s Base64.getUrlEncoder().

In Java, new String(Base64.getUrlEncoder().encode("Hello??".getBytes())) should give you "SGVsbG8_Pw==".

In Kotlin, it’s String(Base64.getUrlEncoder().encode("Hello??".toByteArray())).

Posted 2020-11-17