Tagged: RFC4648
Base 64 Encoding
I just spent a whole week for a twitter xAuth client. And I had to implement Base 64 encoding by myself.
/** * The Base 64 Alphabet. * * 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', * 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', * 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', * 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', * 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', * 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', * 'w', 'x', 'y', 'z', '0', '1', '2', '3', * '4', '5', '6', '7', '8', '9', '+', '/' */ private static final byte[] BASE64_ALPHABET = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F }; public static String base64(final byte[] input) { if (input == null) { throw new NullPointerException("null input"); } int count = input.length / 3; if (input.length % 3 > 0) { count++; } final byte[] output = new byte[count * 4]; int index = 0; int pad = 0; int word; for (int i = 0; i < input.length; i += 3) { word = 0x00; for (int j = 0; j < 3; j++) { if ((i + j) < input.length) { word <<= 8; word |= (input[i + j] & 0xFF); } else { switch (j) { case 1: pad = 2; word <<= 4; break; case 2: pad = 1; word <<= 2; break; default: break; } break; } } for (int j = 0; j < pad; j++) { output[index + 3 - j] = '='; } for (int j = 3 - pad; j >= 0; j--) { output[index + j] = BASE64_ALPHABET[word & 0x3F]; word >>= 6; } if (pad != 0) { break; } index += 4; } return new String(output); }
RFC 4648 The Base16, Base32, and Base64 Data Encodings
RFC 4648 The Base16, Base32, and Base64 Data Encodings
name | bits/char | bytes/word | chars/word | pad | notes |
---|---|---|---|---|---|
base16 (hex) | 4 | 1 | 2 | N/A | |
base32 | 5 | 5 | 8 | YES | |
base32hex | 5 | 5 | 8 | YES | |
base64 | 6 | 3 | 4 | YES | |
base64url | 6 | 3 | 4 | NO |
Base.java
Base16.java
Base32.java
Base32Hex.java
Base64.java
Base64Url.java
import java.io.IOException; import java.util.Arrays; import jinahya.rfc4648.*; public class Test { private static final PrintStream UTF8; static { try { UTF8 = new PrintStream(System.out, true, "UTF-8"); } catch (UnsupportedEncodingException uee) { throw new InstantiationError( "What can I do to make you love me?"); } } private static final String[] WELCOMES = { "Salaam", "Dobrodošli", "歡迎", "欢迎", "歡迎", "Vítáme tĕ", "Velkommen", "Welkom", "Bienvenue", "Wolkom", "Willkommen", "Καλώς ορίσατε", "Aloha", "Shalom", "Benvenuto", "ようこそ", "환영합니다", "Тавтай морилогтун", "Bem-vindo", "Bem-vinda", "Bienvenido", "Välkommen", "Mabuhay", "Swaagatham", "Suswaagatham", "Merhaba"}; public static void main(String[] args) throws IOException { if (args.length == 0) { test(WELCOMES); } else { test(args); } } private static void test(final String[] strings) throws IOException { for (String string : strings) { System.out.printf("%1$5s: %2$s\n", "input", string); final byte[] original = string.getBytes("UTF-8"); System.out.printf("%1$5s: ", "UTF-8"); for (byte b : original) { System.out.printf("%1$s", Integer.toHexString(b & 0xFF)); } System.out.printf("\n"); test("base64", new Base64(), original); test("base64url", new Base64URL(), original); test("base32", new Base32(), original); test("base32hex", new Base32HEX(), original); test("base16", new Base16(), original); } } private static void test(final String name, final Base base, final byte[] original) throws IOException { final char[] encoded = base.encode(original); System.out.printf("\t%1$10s: %2$s\n", name, new String(encoded)); final byte[] decoded = base.decode(encoded); assert Arrays.equals(decoded, original) : "fail"; } }
input: Salaam UTF-8: 53616c61616d base64: U2FsYWFt base64url: U2FsYWFt base32: KNQWYYLBNU====== base32hex: ADGMOOB1DK====== base16: 53616C61616D input: Dobrodošli UTF-8: 446f62726f646fc5a16c69 base64: RG9icm9kb8WhbGk= base64url: RG9icm9kb8WhbGk base32: IRXWE4TPMRX4LILMNE====== base32hex: 8HNM4SJFCHNSB8BCD4====== base16: 446F62726F646FC5A16C69 input: 歡迎 UTF-8: e6ada1e8bf8e base64: 5q2h6L+O base64url: 5q2h6L-O base32: 42W2D2F7RY====== base32hex: SQMQ3Q5VHO====== base16: E6ADA1E8BF8E input: 欢迎 UTF-8: e6aca2e8bf8e base64: 5qyi6L+O base64url: 5qyi6L-O base32: 42WKF2F7RY====== base32hex: SQMA5Q5VHO====== base16: E6ACA2E8BF8E input: 歡迎 UTF-8: e6ada1e8bf8e base64: 5q2h6L+O base64url: 5q2h6L-O base32: 42W2D2F7RY====== base32hex: SQMQ3Q5VHO====== base16: E6ADA1E8BF8E input: Vítáme tĕ UTF-8: 56c3ad74c3a16d652074c495 base64: VsOtdMOhbWUgdMSV base64url: VsOtdMOhbWUgdMSV base32: K3B225GDUFWWKIDUYSKQ==== base32hex: AR1QQT63K5MMA83KOIAG==== base16: 56C3AD74C3A16D652074C495 input: Velkommen UTF-8: 56656c6b6f6d6d656e base64: VmVsa29tbWVu base64url: VmVsa29tbWVu base32: KZSWY23PNVWWK3Q= base32hex: APIMOQRFDLMMARG= base16: 56656C6B6F6D6D656E input: Welkom UTF-8: 57656c6b6f6d base64: V2Vsa29t base64url: V2Vsa29t base32: K5SWY23PNU====== base32hex: ATIMOQRFDK====== base16: 57656C6B6F6D input: Bienvenue UTF-8: 4269656e76656e7565 base64: QmllbnZlbnVl base64url: QmllbnZlbnVl base32: IJUWK3TWMVXHKZI= base32hex: 89KMARJMCLN7AP8= base16: 4269656E76656E7565 input: Wolkom UTF-8: 576f6c6b6f6d base64: V29sa29t base64url: V29sa29t base32: K5XWY23PNU====== base32hex: ATNMOQRFDK====== base16: 576F6C6B6F6D input: Willkommen UTF-8: 57696c6c6b6f6d6d656e base64: V2lsbGtvbW1lbg== base64url: V2lsbGtvbW1lbg base32: K5UWY3DLN5WW2ZLO base32hex: ATKMOR3BDTMMQPBE base16: 57696C6C6B6F6D6D656E input: Καλώς ορίσατε UTF-8: ce9aceb1cebbcf8ecf8220cebfcf81ceafcf83ceb1cf84ceb5 base64: zprOsc67z47PgiDOv8+Bzq/Pg86xz4TOtQ== base64url: zprOsc67z47PgiDOv8-Bzq_Pg86xz4TOtQ base32: Z2NM5MOOXPHY5T4CEDHL7T4BZ2X47A6OWHHYJTVV base32hex: PQDCTCEENF7OTJS2437BVJS1PQNSV0UEM77O9JLL base16: CE9ACEB1CEBBCF8ECF8220CEBFCF81CEAFCF83CEB1CF84CEB5 input: Aloha UTF-8: 416c6f6861 base64: QWxvaGE= base64url: QWxvaGE base32: IFWG62DB base32hex: 85M6UQ31 base16: 416C6F6861 input: Shalom UTF-8: 5368616c6f6d base64: U2hhbG9t base64url: U2hhbG9t base32: KNUGC3DPNU====== base32hex: ADK62R3FDK====== base16: 5368616C6F6D input: Benvenuto UTF-8: 42656e76656e75746f base64: QmVudmVudXRv base64url: QmVudmVudXRv base32: IJSW45TFNZ2XI3Y= base32hex: 89IMSTJ5DPQN8RO= base16: 42656E76656E75746F input: ようこそ UTF-8: e38288e38186e38193e3819d base64: 44KI44GG44GT44Gd base64url: 44KI44GG44GT44Gd base32: 4OBIRY4BQ3RYDE7DQGOQ==== base32hex: SE18HOS1GRHO34V3G6EG==== base16: E38288E38186E38193E3819D input: 환영합니다 UTF-8: ed9998ec9881ed95a9eb8b88eb8ba4 base64: 7ZmY7JiB7ZWp64uI64uk base64url: 7ZmY7JiB7ZWp64uI64uk base32: 5WMZR3EYQHWZLKPLROEOXC5E base32hex: TMCPHR4OG7MPBAFBHE4EN2T4 base16: ED9998EC9881ED95A9EB8B88EB8BA4 input: Тавтай морилогтун UTF-8: d0a2d0b0d0b2d182d0b0d0b920d0bcd0bed180d0b8d0bbd0bed0b3d182d183d0bd base64: 0KLQsNCy0YLQsNC5INC80L7RgNC40LvQvtCz0YLRg9C9 base64url: 0KLQsNCy0YLQsNC5INC80L7RgNC40LvQvtCz0YLRg9C9 base32: 2CRNBMGQWLIYFUFQ2C4SBUF42C7NDAGQXDILXUF62CZ5DAWRQPIL2=== base32hex: Q2HD1C6GMB8O5K5GQ2SI1K5SQ2VD306GN38BNK5UQ2PT30MHGF8BQ=== base16: D0A2D0B0D0B2D182D0B0D0B920D0BCD0BED180D0B8D0BBD0BED0B3D182D183D0BD input: Bem-vindo UTF-8: 42656d2d76696e646f base64: QmVtLXZpbmRv base64url: QmVtLXZpbmRv base32: IJSW2LLWNFXGI3Y= base32hex: 89IMQBBMD5N68RO= base16: 42656D2D76696E646F input: Bem-vinda UTF-8: 42656d2d76696e6461 base64: QmVtLXZpbmRh base64url: QmVtLXZpbmRh base32: IJSW2LLWNFXGIYI= base32hex: 89IMQBBMD5N68O8= base16: 42656D2D76696E6461 input: Bienvenido UTF-8: 4269656e76656e69646f base64: QmllbnZlbmlkbw== base64url: QmllbnZlbmlkbw base32: IJUWK3TWMVXGSZDP base32hex: 89KMARJMCLN6IP3F base16: 4269656E76656E69646F input: Välkommen UTF-8: 56c3a46c6b6f6d6d656e base64: VsOkbGtvbW1lbg== base64url: VsOkbGtvbW1lbg base32: K3B2I3DLN5WW2ZLO base32hex: AR1Q8R3BDTMMQPBE base16: 56C3A46C6B6F6D6D656E input: Mabuhay UTF-8: 4d616275686179 base64: TWFidWhheQ== base64url: TWFidWhheQ base32: JVQWE5LIMF4Q==== base32hex: 9LGM4TB8C5SG==== base16: 4D616275686179 input: Swaagatham UTF-8: 5377616167617468616d base64: U3dhYWdhdGhhbQ== base64url: U3dhYWdhdGhhbQ base32: KN3WCYLHMF2GQYLN base32hex: ADRM2OB7C5Q6GOBD base16: 5377616167617468616D input: Suswaagatham UTF-8: 53757377616167617468616d base64: U3Vzd2FhZ2F0aGFt base64url: U3Vzd2FhZ2F0aGFt base32: KN2XG53BMFTWC5DIMFWQ==== base32hex: ADQN6TR1C5JM2T38C5MG==== base16: 53757377616167617468616D input: Merhaba UTF-8: 4d657268616261 base64: TWVyaGFiYQ== base64url: TWVyaGFiYQ base32: JVSXE2DBMJQQ==== base32hex: 9LIN4Q31C9GG==== base16: 4D657268616261