001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.commons.codec.binary;
019
020import static org.junit.Assert.assertEquals;
021import static org.junit.Assert.assertFalse;
022import static org.junit.Assert.assertNotNull;
023import static org.junit.Assert.assertTrue;
024import static org.junit.Assert.fail;
025
026import java.math.BigInteger;
027import java.util.Arrays;
028import java.util.Random;
029
030import org.apache.commons.codec.Charsets;
031import org.apache.commons.codec.DecoderException;
032import org.apache.commons.codec.EncoderException;
033import org.junit.Ignore;
034import org.junit.Test;
035
036/**
037 * Test cases for Base64 class.
038 *
039 * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>
040 * @version $Id: Base64Test.html 891688 2013-12-24 20:49:46Z ggregory $
041 */
042public class Base64Test {
043
044    private final Random random = new Random();
045
046    /**
047     * @return Returns the random.
048     */
049    public Random getRandom() {
050        return this.random;
051    }
052
053    /**
054     * Test the isStringBase64 method.
055     */
056    @Test
057    public void testIsStringBase64() {
058        final String nullString = null;
059        final String emptyString = "";
060        final String validString = "abc===defg\n\r123456\r789\r\rABC\n\nDEF==GHI\r\nJKL==============";
061        final String invalidString = validString + (char)0; // append null character
062
063        try {
064            Base64.isBase64(nullString);
065            fail("Base64.isStringBase64() should not be null-safe.");
066        } catch (final NullPointerException npe) {
067            assertNotNull("Base64.isStringBase64() should not be null-safe.", npe);
068        }
069
070        assertTrue("Base64.isStringBase64(empty-string) is true", Base64.isBase64(emptyString));
071        assertTrue("Base64.isStringBase64(valid-string) is true", Base64.isBase64(validString));
072        assertFalse("Base64.isStringBase64(invalid-string) is false", Base64.isBase64(invalidString));
073    }
074
075    /**
076     * Test the Base64 implementation
077     */
078    @Test
079    public void testBase64() {
080        final String content = "Hello World";
081        String encodedContent;
082        byte[] encodedBytes = Base64.encodeBase64(StringUtils.getBytesUtf8(content));
083        encodedContent = StringUtils.newStringUtf8(encodedBytes);
084        assertEquals("encoding hello world", "SGVsbG8gV29ybGQ=", encodedContent);
085
086        Base64 b64 = new Base64(BaseNCodec.MIME_CHUNK_SIZE, null);  // null lineSeparator same as saying no-chunking
087        encodedBytes = b64.encode(StringUtils.getBytesUtf8(content));
088        encodedContent = StringUtils.newStringUtf8(encodedBytes);
089        assertEquals("encoding hello world", "SGVsbG8gV29ybGQ=", encodedContent);
090
091        b64 = new Base64(0, null);  // null lineSeparator same as saying no-chunking
092        encodedBytes = b64.encode(StringUtils.getBytesUtf8(content));
093        encodedContent = StringUtils.newStringUtf8(encodedBytes);
094        assertEquals("encoding hello world", "SGVsbG8gV29ybGQ=", encodedContent);
095
096        // bogus characters to decode (to skip actually) {e-acute*6}
097        final byte[] decode = b64.decode("SGVsbG{\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9}8gV29ybGQ=");
098        final String decodeString = StringUtils.newStringUtf8(decode);
099        assertEquals("decode hello world", "Hello World", decodeString);
100    }
101
102    /**
103     * Test our decode with pad character in the middle.
104     * (Our current implementation:  halt decode and return what we've got so far).
105     *
106     * The point of this test is not to say "this is the correct way to decode base64."
107     * The point is simply to keep us aware of the current logic since 1.4 so we
108     * don't accidentally break it without realizing.
109     *
110     * Note for historians.  The 1.3 logic would decode to:
111     * "Hello World\u0000Hello World" -- null in the middle ---
112     * and 1.4 unwittingly changed it to current logic.
113     */
114    @Test
115    public void testDecodeWithInnerPad() {
116        final String content = "SGVsbG8gV29ybGQ=SGVsbG8gV29ybGQ=";
117        final byte[] result = Base64.decodeBase64(content);
118        final byte[] shouldBe = StringUtils.getBytesUtf8("Hello World");
119        assertTrue("decode should halt at pad (=)", Arrays.equals(result, shouldBe));
120    }
121
122    /**
123     * Tests Base64.encodeBase64().
124     */
125    @Test
126    public void testChunkedEncodeMultipleOf76() {
127        final byte[] expectedEncode = Base64.encodeBase64(Base64TestData.DECODED, true);
128        // convert to "\r\n" so we're equal to the old openssl encoding test stored
129        // in Base64TestData.ENCODED_76_CHARS_PER_LINE:
130        final String actualResult = Base64TestData.ENCODED_76_CHARS_PER_LINE.replaceAll("\n", "\r\n");
131        final byte[] actualEncode = StringUtils.getBytesUtf8(actualResult);
132        assertTrue("chunkedEncodeMultipleOf76", Arrays.equals(expectedEncode, actualEncode));
133    }
134
135    /**
136     * CODEC-68: isBase64 throws ArrayIndexOutOfBoundsException on some non-BASE64 bytes
137     */
138    @Test
139    public void testCodec68() {
140        final byte[] x = new byte[]{'n', 'A', '=', '=', (byte) 0x9c};
141        Base64.decodeBase64(x);
142    }
143
144    @Test
145    public void testCodeInteger1() {
146        final String encodedInt1 = "li7dzDacuo67Jg7mtqEm2TRuOMU=";
147        final BigInteger bigInt1 = new BigInteger("85739377120809420210425962799" + "0318636601332086981");
148
149        assertEquals(encodedInt1, new String(Base64.encodeInteger(bigInt1)));
150        assertEquals(bigInt1, Base64.decodeInteger(encodedInt1.getBytes(Charsets.UTF_8)));
151    }
152
153    @Test
154    public void testCodeInteger2() {
155        final String encodedInt2 = "9B5ypLY9pMOmtxCeTDHgwdNFeGs=";
156        final BigInteger bigInt2 = new BigInteger("13936727572861167254666467268" + "91466679477132949611");
157
158        assertEquals(encodedInt2, new String(Base64.encodeInteger(bigInt2)));
159        assertEquals(bigInt2, Base64.decodeInteger(encodedInt2.getBytes(Charsets.UTF_8)));
160    }
161
162    @Test
163    public void testCodeInteger3() {
164        final String encodedInt3 = "FKIhdgaG5LGKiEtF1vHy4f3y700zaD6QwDS3IrNVGzNp2" + "rY+1LFWTK6D44AyiC1n8uWz1itkYMZF0/aKDK0Yjg==";
165        final BigInteger bigInt3 = new BigInteger("10806548154093873461951748545"
166            + "1196989136416448805819079363524309897749044958112417136240557"
167            + "4495062430572478766856090958495998158114332651671116876320938126");
168
169        assertEquals(encodedInt3, new String(Base64.encodeInteger(bigInt3)));
170        assertEquals(bigInt3, Base64.decodeInteger(encodedInt3.getBytes(Charsets.UTF_8)));
171    }
172
173    @Test
174    public void testCodeInteger4() {
175        final String encodedInt4 = "ctA8YGxrtngg/zKVvqEOefnwmViFztcnPBYPlJsvh6yKI"
176            + "4iDm68fnp4Mi3RrJ6bZAygFrUIQLxLjV+OJtgJAEto0xAs+Mehuq1DkSFEpP3o"
177            + "DzCTOsrOiS1DwQe4oIb7zVk/9l7aPtJMHW0LVlMdwZNFNNJoqMcT2ZfCPrfvYv"
178            + "Q0=";
179        final BigInteger bigInt4 = new BigInteger("80624726256040348115552042320"
180            + "6968135001872753709424419772586693950232350200555646471175944"
181            + "519297087885987040810778908507262272892702303774422853675597"
182            + "748008534040890923814202286633163248086055216976551456088015"
183            + "338880713818192088877057717530169381044092839402438015097654"
184            + "53542091716518238707344493641683483917");
185
186        assertEquals(encodedInt4, new String(Base64.encodeInteger(bigInt4)));
187        assertEquals(bigInt4, Base64.decodeInteger(encodedInt4.getBytes(Charsets.UTF_8)));
188    }
189
190    @Test
191    public void testCodeIntegerEdgeCases() {
192        // TODO
193    }
194
195    @Test
196    public void testCodeIntegerNull() {
197        try {
198            Base64.encodeInteger(null);
199            fail("Exception not thrown when passing in null to encodeInteger(BigInteger)");
200        } catch (final NullPointerException npe) {
201            // expected
202        } catch (final Exception e) {
203            fail("Incorrect Exception caught when passing in null to encodeInteger(BigInteger)");
204        }
205    }
206
207    @Test
208    public void testConstructors() {
209        Base64 base64;
210        base64 = new Base64();
211        base64 = new Base64(-1);
212        base64 = new Base64(-1, new byte[]{});
213        base64 = new Base64(64, new byte[]{});
214        try {
215            base64 = new Base64(-1, new byte[]{'A'}); // TODO do we need to check sep if len = -1?
216            fail("Should have rejected attempt to use 'A' as a line separator");
217        } catch (final IllegalArgumentException ignored) {
218            // Expected
219        }
220        try {
221            base64 = new Base64(64, new byte[]{'A'});
222            fail("Should have rejected attempt to use 'A' as a line separator");
223        } catch (final IllegalArgumentException ignored) {
224            // Expected
225        }
226        try {
227            base64 = new Base64(64, new byte[]{'='});
228            fail("Should have rejected attempt to use '=' as a line separator");
229        } catch (final IllegalArgumentException ignored) {
230            // Expected
231        }
232        base64 = new Base64(64, new byte[]{'$'}); // OK
233        try {
234            base64 = new Base64(64, new byte[]{'A', '$'});
235            fail("Should have rejected attempt to use 'A$' as a line separator");
236        } catch (final IllegalArgumentException ignored) {
237            // Expected
238        }
239        base64 = new Base64(64, new byte[]{' ', '$', '\n', '\r', '\t'}); // OK
240        assertNotNull(base64);
241    }
242
243    @Test
244    public void testConstructor_Int_ByteArray_Boolean() {
245        final Base64 base64 = new Base64(65, new byte[]{'\t'}, false);
246        final byte[] encoded = base64.encode(Base64TestData.DECODED);
247        String expectedResult = Base64TestData.ENCODED_64_CHARS_PER_LINE;
248        expectedResult = expectedResult.replace('\n', '\t');
249        final String result = StringUtils.newStringUtf8(encoded);
250        assertEquals("new Base64(65, \\t, false)", expectedResult, result);
251    }
252
253    @Test
254    public void testConstructor_Int_ByteArray_Boolean_UrlSafe() {
255        // url-safe variation
256        final Base64 base64 = new Base64(64, new byte[]{'\t'}, true);
257        final byte[] encoded = base64.encode(Base64TestData.DECODED);
258        String expectedResult = Base64TestData.ENCODED_64_CHARS_PER_LINE;
259        expectedResult = expectedResult.replaceAll("=", ""); // url-safe has no == padding.
260        expectedResult = expectedResult.replace('\n', '\t');
261        expectedResult = expectedResult.replace('+', '-');
262        expectedResult = expectedResult.replace('/', '_');
263        final String result = StringUtils.newStringUtf8(encoded);
264        assertEquals("new Base64(64, \\t, true)", result, expectedResult);
265    }
266
267    /**
268     * Tests conditional true branch for "marker0" test.
269     */
270    @Test
271    public void testDecodePadMarkerIndex2() {
272        assertEquals("A", new String(Base64.decodeBase64("QQ==".getBytes(Charsets.UTF_8))));
273    }
274
275    /**
276     * Tests conditional branches for "marker1" test.
277     */
278    @Test
279    public void testDecodePadMarkerIndex3() {
280        assertEquals("AA", new String(Base64.decodeBase64("QUE=".getBytes(Charsets.UTF_8))));
281        assertEquals("AAA", new String(Base64.decodeBase64("QUFB".getBytes(Charsets.UTF_8))));
282    }
283
284    @Test
285    public void testDecodePadOnly() {
286        assertEquals(0, Base64.decodeBase64("====".getBytes(Charsets.UTF_8)).length);
287        assertEquals("", new String(Base64.decodeBase64("====".getBytes(Charsets.UTF_8))));
288        // Test truncated padding
289        assertEquals(0, Base64.decodeBase64("===".getBytes(Charsets.UTF_8)).length);
290        assertEquals(0, Base64.decodeBase64("==".getBytes(Charsets.UTF_8)).length);
291        assertEquals(0, Base64.decodeBase64("=".getBytes(Charsets.UTF_8)).length);
292        assertEquals(0, Base64.decodeBase64("".getBytes(Charsets.UTF_8)).length);
293    }
294
295    @Test
296    public void testDecodePadOnlyChunked() {
297        assertEquals(0, Base64.decodeBase64("====\n".getBytes(Charsets.UTF_8)).length);
298        assertEquals("", new String(Base64.decodeBase64("====\n".getBytes(Charsets.UTF_8))));
299        // Test truncated padding
300        assertEquals(0, Base64.decodeBase64("===\n".getBytes(Charsets.UTF_8)).length);
301        assertEquals(0, Base64.decodeBase64("==\n".getBytes(Charsets.UTF_8)).length);
302        assertEquals(0, Base64.decodeBase64("=\n".getBytes(Charsets.UTF_8)).length);
303        assertEquals(0, Base64.decodeBase64("\n".getBytes(Charsets.UTF_8)).length);
304    }
305
306    @Test
307    public void testDecodeWithWhitespace() throws Exception {
308
309        final String orig = "I am a late night coder.";
310
311        final byte[] encodedArray = Base64.encodeBase64(orig.getBytes(Charsets.UTF_8));
312        final StringBuilder intermediate = new StringBuilder(new String(encodedArray));
313
314        intermediate.insert(2, ' ');
315        intermediate.insert(5, '\t');
316        intermediate.insert(10, '\r');
317        intermediate.insert(15, '\n');
318
319        final byte[] encodedWithWS = intermediate.toString().getBytes(Charsets.UTF_8);
320        final byte[] decodedWithWS = Base64.decodeBase64(encodedWithWS);
321
322        final String dest = new String(decodedWithWS);
323
324        assertEquals("Dest string doesn't equal the original", orig, dest);
325    }
326
327    /**
328     * Test encode and decode of empty byte array.
329     */
330    @Test
331    public void testEmptyBase64() {
332        byte[] empty = new byte[0];
333        byte[] result = Base64.encodeBase64(empty);
334        assertEquals("empty base64 encode", 0, result.length);
335        assertEquals("empty base64 encode", null, Base64.encodeBase64(null));
336
337        empty = new byte[0];
338        result = Base64.decodeBase64(empty);
339        assertEquals("empty base64 decode", 0, result.length);
340        assertEquals("empty base64 encode", null, Base64.decodeBase64((byte[]) null));
341    }
342
343    // encode/decode a large random array
344    @Test
345    public void testEncodeDecodeRandom() {
346        for (int i = 1; i < 5; i++) {
347            final byte[] data = new byte[this.getRandom().nextInt(10000) + 1];
348            this.getRandom().nextBytes(data);
349            final byte[] enc = Base64.encodeBase64(data);
350            assertTrue(Base64.isBase64(enc));
351            final byte[] data2 = Base64.decodeBase64(enc);
352            assertTrue(Arrays.equals(data, data2));
353        }
354    }
355
356    // encode/decode random arrays from size 0 to size 11
357    @Test
358    public void testEncodeDecodeSmall() {
359        for (int i = 0; i < 12; i++) {
360            final byte[] data = new byte[i];
361            this.getRandom().nextBytes(data);
362            final byte[] enc = Base64.encodeBase64(data);
363            assertTrue("\"" + new String(enc) + "\" is Base64 data.", Base64.isBase64(enc));
364            final byte[] data2 = Base64.decodeBase64(enc);
365            assertTrue(toString(data) + " equals " + toString(data2), Arrays.equals(data, data2));
366        }
367    }
368
369    @Test
370    public void testEncodeOverMaxSize() throws Exception {
371        testEncodeOverMaxSize(-1);
372        testEncodeOverMaxSize(0);
373        testEncodeOverMaxSize(1);
374        testEncodeOverMaxSize(2);
375    }
376
377    @Test
378    public void testCodec112() { // size calculation assumes always chunked
379        final byte[] in = new byte[] {0};
380        final byte[] out=Base64.encodeBase64(in);
381        Base64.encodeBase64(in, false, false, out.length);
382    }
383
384    private void testEncodeOverMaxSize(final int maxSize) throws Exception {
385        try {
386            Base64.encodeBase64(Base64TestData.DECODED, true, false, maxSize);
387            fail("Expected " + IllegalArgumentException.class.getName());
388        } catch (final IllegalArgumentException e) {
389            // Expected
390        }
391    }
392
393    @Test
394    public void testIgnoringNonBase64InDecode() throws Exception {
395        assertEquals("The quick brown fox jumped over the lazy dogs.", new String(Base64
396                .decodeBase64("VGhlIH@$#$@%F1aWN@#@#@@rIGJyb3duIGZve\n\r\t%#%#%#%CBqd##$#$W1wZWQgb3ZlciB0aGUgbGF6eSBkb2dzLg==".getBytes(Charsets.UTF_8))));
397    }
398
399    @Test
400    public void testIsArrayByteBase64() {
401        assertFalse(Base64.isBase64(new byte[]{Byte.MIN_VALUE}));
402        assertFalse(Base64.isBase64(new byte[]{-125}));
403        assertFalse(Base64.isBase64(new byte[]{-10}));
404        assertFalse(Base64.isBase64(new byte[]{0}));
405        assertFalse(Base64.isBase64(new byte[]{64, Byte.MAX_VALUE}));
406        assertFalse(Base64.isBase64(new byte[]{Byte.MAX_VALUE}));
407        assertTrue(Base64.isBase64(new byte[]{'A'}));
408        assertFalse(Base64.isBase64(new byte[]{'A', Byte.MIN_VALUE}));
409        assertTrue(Base64.isBase64(new byte[]{'A', 'Z', 'a'}));
410        assertTrue(Base64.isBase64(new byte[]{'/', '=', '+'}));
411        assertFalse(Base64.isBase64(new byte[]{'$'}));
412    }
413
414    /**
415     * Tests isUrlSafe.
416     */
417    @Test
418    public void testIsUrlSafe() {
419        final Base64 base64Standard = new Base64(false);
420        final Base64 base64URLSafe = new Base64(true);
421
422        assertFalse("Base64.isUrlSafe=false", base64Standard.isUrlSafe());
423        assertTrue("Base64.isUrlSafe=true", base64URLSafe.isUrlSafe());
424
425        final byte[] whiteSpace = {' ', '\n', '\r', '\t'};
426        assertTrue("Base64.isBase64(whiteSpace)=true", Base64.isBase64(whiteSpace));
427    }
428
429    @Test
430    public void testKnownDecodings() {
431        assertEquals("The quick brown fox jumped over the lazy dogs.", new String(Base64
432                .decodeBase64("VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2dzLg==".getBytes(Charsets.UTF_8))));
433        assertEquals("It was the best of times, it was the worst of times.", new String(Base64
434                .decodeBase64("SXQgd2FzIHRoZSBiZXN0IG9mIHRpbWVzLCBpdCB3YXMgdGhlIHdvcnN0IG9mIHRpbWVzLg==".getBytes(Charsets.UTF_8))));
435        assertEquals("http://jakarta.apache.org/commmons", new String(Base64
436                .decodeBase64("aHR0cDovL2pha2FydGEuYXBhY2hlLm9yZy9jb21tbW9ucw==".getBytes(Charsets.UTF_8))));
437        assertEquals("AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz", new String(Base64
438                .decodeBase64("QWFCYkNjRGRFZUZmR2dIaElpSmpLa0xsTW1Obk9vUHBRcVJyU3NUdFV1VnZXd1h4WXlaeg==".getBytes(Charsets.UTF_8))));
439        assertEquals("{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }", new String(Base64.decodeBase64("eyAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5IH0="
440                .getBytes(Charsets.UTF_8))));
441        assertEquals("xyzzy!", new String(Base64.decodeBase64("eHl6enkh".getBytes(Charsets.UTF_8))));
442    }
443
444    @Test
445    public void testKnownEncodings() {
446        assertEquals("VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2dzLg==", new String(Base64
447                .encodeBase64("The quick brown fox jumped over the lazy dogs.".getBytes(Charsets.UTF_8))));
448        assertEquals(
449                "YmxhaCBibGFoIGJsYWggYmxhaCBibGFoIGJsYWggYmxhaCBibGFoIGJsYWggYmxhaCBibGFoIGJs\r\nYWggYmxhaCBibGFoIGJsYWggYmxhaCBibGFoIGJsYWggYmxhaCBibGFoIGJsYWggYmxhaCBibGFo\r\nIGJsYWggYmxhaCBibGFoIGJsYWggYmxhaCBibGFoIGJsYWggYmxhaCBibGFoIGJsYWggYmxhaCBi\r\nbGFoIGJsYWg=\r\n",
450                new String(
451                        Base64
452                                .encodeBase64Chunked("blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah"
453                                        .getBytes(Charsets.UTF_8))));
454        assertEquals("SXQgd2FzIHRoZSBiZXN0IG9mIHRpbWVzLCBpdCB3YXMgdGhlIHdvcnN0IG9mIHRpbWVzLg==", new String(Base64
455                .encodeBase64("It was the best of times, it was the worst of times.".getBytes(Charsets.UTF_8))));
456        assertEquals("aHR0cDovL2pha2FydGEuYXBhY2hlLm9yZy9jb21tbW9ucw==", new String(Base64
457                .encodeBase64("http://jakarta.apache.org/commmons".getBytes(Charsets.UTF_8))));
458        assertEquals("QWFCYkNjRGRFZUZmR2dIaElpSmpLa0xsTW1Obk9vUHBRcVJyU3NUdFV1VnZXd1h4WXlaeg==", new String(Base64
459                .encodeBase64("AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz".getBytes(Charsets.UTF_8))));
460        assertEquals("eyAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5IH0=", new String(Base64.encodeBase64("{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }"
461                .getBytes(Charsets.UTF_8))));
462        assertEquals("eHl6enkh", new String(Base64.encodeBase64("xyzzy!".getBytes(Charsets.UTF_8))));
463    }
464
465    @Test
466    public void testNonBase64Test() throws Exception {
467
468        final byte[] bArray = {'%'};
469
470        assertFalse("Invalid Base64 array was incorrectly validated as " + "an array of Base64 encoded data", Base64
471                .isBase64(bArray));
472
473        try {
474            final Base64 b64 = new Base64();
475            final byte[] result = b64.decode(bArray);
476
477            assertEquals("The result should be empty as the test encoded content did " + "not contain any valid base 64 characters",
478                    0, result.length);
479        } catch (final Exception e) {
480            fail("Exception was thrown when trying to decode "
481                + "invalid base64 encoded data - RFC 2045 requires that all "
482                + "non base64 character be discarded, an exception should not"
483                + " have been thrown");
484        }
485    }
486
487    @Test
488    public void testObjectDecodeWithInvalidParameter() throws Exception {
489        final Base64 b64 = new Base64();
490
491        try {
492            b64.decode(Integer.valueOf(5));
493            fail("decode(Object) didn't throw an exception when passed an Integer object");
494        } catch (final DecoderException e) {
495            // ignored
496        }
497
498    }
499
500    @Test
501    public void testObjectDecodeWithValidParameter() throws Exception {
502
503        final String original = "Hello World!";
504        final Object o = Base64.encodeBase64(original.getBytes(Charsets.UTF_8));
505
506        final Base64 b64 = new Base64();
507        final Object oDecoded = b64.decode(o);
508        final byte[] baDecoded = (byte[]) oDecoded;
509        final String dest = new String(baDecoded);
510
511        assertEquals("dest string does not equal original", original, dest);
512    }
513
514    @Test
515    public void testObjectEncodeWithInvalidParameter() throws Exception {
516        final Base64 b64 = new Base64();
517        try {
518            b64.encode("Yadayadayada");
519            fail("encode(Object) didn't throw an exception when passed a String object");
520        } catch (final EncoderException e) {
521            // Expected
522        }
523    }
524
525    @Test
526    public void testObjectEncodeWithValidParameter() throws Exception {
527
528        final String original = "Hello World!";
529        final Object origObj = original.getBytes(Charsets.UTF_8);
530
531        final Base64 b64 = new Base64();
532        final Object oEncoded = b64.encode(origObj);
533        final byte[] bArray = Base64.decodeBase64((byte[]) oEncoded);
534        final String dest = new String(bArray);
535
536        assertEquals("dest string does not equal original", original, dest);
537    }
538
539    @Test
540    public void testObjectEncode() throws Exception {
541        final Base64 b64 = new Base64();
542        assertEquals("SGVsbG8gV29ybGQ=", new String(b64.encode("Hello World".getBytes(Charsets.UTF_8))));
543    }
544
545    @Test
546    public void testPairs() {
547        assertEquals("AAA=", new String(Base64.encodeBase64(new byte[]{0, 0})));
548        for (int i = -128; i <= 127; i++) {
549            final byte test[] = {(byte) i, (byte) i};
550            assertTrue(Arrays.equals(test, Base64.decodeBase64(Base64.encodeBase64(test))));
551        }
552    }
553
554    /**
555     * Tests RFC 2045 section 2.1 CRLF definition.
556     */
557    @Test
558    public void testRfc2045Section2Dot1CrLfDefinition() {
559        assertTrue(Arrays.equals(new byte[]{13, 10}, Base64.CHUNK_SEPARATOR));
560    }
561
562    /**
563     * Tests RFC 2045 section 6.8 chuck size definition.
564     */
565    @Test
566    public void testRfc2045Section6Dot8ChunkSizeDefinition() {
567        assertEquals(76, BaseNCodec.MIME_CHUNK_SIZE);
568    }
569
570    /**
571     * Tests RFC 1421 section 4.3.2.4 chuck size definition.
572     */
573    @Test
574    public void testRfc1421Section6Dot8ChunkSizeDefinition() {
575        assertEquals(64, BaseNCodec.PEM_CHUNK_SIZE);
576    }
577
578    /**
579     * Tests RFC 4648 section 10 test vectors.
580     * <ul>
581     * <li>BASE64("") = ""</li>
582     * <li>BASE64("f") = "Zg=="</li>
583     * <li>BASE64("fo") = "Zm8="</li>
584     * <li>BASE64("foo") = "Zm9v"</li>
585     * <li>BASE64("foob") = "Zm9vYg=="</li>
586     * <li>BASE64("fooba") = "Zm9vYmE="</li>
587     * <li>BASE64("foobar") = "Zm9vYmFy"</li>
588     * </ul>
589     *
590     * @see <a href="http://tools.ietf.org/html/rfc4648">http://tools.ietf.org/html/rfc4648</a>
591     */
592    @Test
593    public void testRfc4648Section10Decode() {
594        assertEquals("", StringUtils.newStringUsAscii(Base64.decodeBase64("")));
595        assertEquals("f", StringUtils.newStringUsAscii(Base64.decodeBase64("Zg==")));
596        assertEquals("fo", StringUtils.newStringUsAscii(Base64.decodeBase64("Zm8=")));
597        assertEquals("foo", StringUtils.newStringUsAscii(Base64.decodeBase64("Zm9v")));
598        assertEquals("foob", StringUtils.newStringUsAscii(Base64.decodeBase64("Zm9vYg==")));
599        assertEquals("fooba", StringUtils.newStringUsAscii(Base64.decodeBase64("Zm9vYmE=")));
600        assertEquals("foobar", StringUtils.newStringUsAscii(Base64.decodeBase64("Zm9vYmFy")));
601    }
602
603    /**
604     * Tests RFC 4648 section 10 test vectors.
605     * <ul>
606     * <li>BASE64("") = ""</li>
607     * <li>BASE64("f") = "Zg=="</li>
608     * <li>BASE64("fo") = "Zm8="</li>
609     * <li>BASE64("foo") = "Zm9v"</li>
610     * <li>BASE64("foob") = "Zm9vYg=="</li>
611     * <li>BASE64("fooba") = "Zm9vYmE="</li>
612     * <li>BASE64("foobar") = "Zm9vYmFy"</li>
613     * </ul>
614     *
615     * @see <a href="http://tools.ietf.org/html/rfc4648">http://tools.ietf.org/html/rfc4648</a>
616     */
617    @Test
618    public void testRfc4648Section10DecodeWithCrLf() {
619        final String CRLF = StringUtils.newStringUsAscii(Base64.CHUNK_SEPARATOR);
620        assertEquals("", StringUtils.newStringUsAscii(Base64.decodeBase64("" + CRLF)));
621        assertEquals("f", StringUtils.newStringUsAscii(Base64.decodeBase64("Zg==" + CRLF)));
622        assertEquals("fo", StringUtils.newStringUsAscii(Base64.decodeBase64("Zm8=" + CRLF)));
623        assertEquals("foo", StringUtils.newStringUsAscii(Base64.decodeBase64("Zm9v" + CRLF)));
624        assertEquals("foob", StringUtils.newStringUsAscii(Base64.decodeBase64("Zm9vYg==" + CRLF)));
625        assertEquals("fooba", StringUtils.newStringUsAscii(Base64.decodeBase64("Zm9vYmE=" + CRLF)));
626        assertEquals("foobar", StringUtils.newStringUsAscii(Base64.decodeBase64("Zm9vYmFy" + CRLF)));
627    }
628
629    /**
630     * Tests RFC 4648 section 10 test vectors.
631     * <ul>
632     * <li>BASE64("") = ""</li>
633     * <li>BASE64("f") = "Zg=="</li>
634     * <li>BASE64("fo") = "Zm8="</li>
635     * <li>BASE64("foo") = "Zm9v"</li>
636     * <li>BASE64("foob") = "Zm9vYg=="</li>
637     * <li>BASE64("fooba") = "Zm9vYmE="</li>
638     * <li>BASE64("foobar") = "Zm9vYmFy"</li>
639     * </ul>
640     *
641     * @see <a href="http://tools.ietf.org/html/rfc4648">http://tools.ietf.org/html/rfc4648</a>
642     */
643    @Test
644    public void testRfc4648Section10Encode() {
645        assertEquals("", Base64.encodeBase64String(StringUtils.getBytesUtf8("")));
646        assertEquals("Zg==", Base64.encodeBase64String(StringUtils.getBytesUtf8("f")));
647        assertEquals("Zm8=", Base64.encodeBase64String(StringUtils.getBytesUtf8("fo")));
648        assertEquals("Zm9v", Base64.encodeBase64String(StringUtils.getBytesUtf8("foo")));
649        assertEquals("Zm9vYg==", Base64.encodeBase64String(StringUtils.getBytesUtf8("foob")));
650        assertEquals("Zm9vYmE=", Base64.encodeBase64String(StringUtils.getBytesUtf8("fooba")));
651        assertEquals("Zm9vYmFy", Base64.encodeBase64String(StringUtils.getBytesUtf8("foobar")));
652    }
653
654    /**
655     * Tests RFC 4648 section 10 test vectors.
656     * <ul>
657     * <li>BASE64("") = ""</li>
658     * <li>BASE64("f") = "Zg=="</li>
659     * <li>BASE64("fo") = "Zm8="</li>
660     * <li>BASE64("foo") = "Zm9v"</li>
661     * <li>BASE64("foob") = "Zm9vYg=="</li>
662     * <li>BASE64("fooba") = "Zm9vYmE="</li>
663     * <li>BASE64("foobar") = "Zm9vYmFy"</li>
664     * </ul>
665     *
666     * @see <a href="http://tools.ietf.org/html/rfc4648">http://tools.ietf.org/html/rfc4648</a>
667     */
668    @Test
669    public void testRfc4648Section10DecodeEncode() {
670        testDecodeEncode("");
671        testDecodeEncode("Zg==");
672        testDecodeEncode("Zm8=");
673        testDecodeEncode("Zm9v");
674        testDecodeEncode("Zm9vYg==");
675        testDecodeEncode("Zm9vYmE=");
676        testDecodeEncode("Zm9vYmFy");
677    }
678
679    private void testDecodeEncode(final String encodedText) {
680        final String decodedText = StringUtils.newStringUsAscii(Base64.decodeBase64(encodedText));
681        final String encodedText2 = Base64.encodeBase64String(StringUtils.getBytesUtf8(decodedText));
682        assertEquals(encodedText, encodedText2);
683    }
684
685    /**
686     * Tests RFC 4648 section 10 test vectors.
687     * <ul>
688     * <li>BASE64("") = ""</li>
689     * <li>BASE64("f") = "Zg=="</li>
690     * <li>BASE64("fo") = "Zm8="</li>
691     * <li>BASE64("foo") = "Zm9v"</li>
692     * <li>BASE64("foob") = "Zm9vYg=="</li>
693     * <li>BASE64("fooba") = "Zm9vYmE="</li>
694     * <li>BASE64("foobar") = "Zm9vYmFy"</li>
695     * </ul>
696     *
697     * @see <a href="http://tools.ietf.org/html/rfc4648">http://tools.ietf.org/html/rfc4648</a>
698     */
699    @Test
700    public void testRfc4648Section10EncodeDecode() {
701        testEncodeDecode("");
702        testEncodeDecode("f");
703        testEncodeDecode("fo");
704        testEncodeDecode("foo");
705        testEncodeDecode("foob");
706        testEncodeDecode("fooba");
707        testEncodeDecode("foobar");
708    }
709
710    private void testEncodeDecode(final String plainText) {
711        final String encodedText = Base64.encodeBase64String(StringUtils.getBytesUtf8(plainText));
712        final String decodedText = StringUtils.newStringUsAscii(Base64.decodeBase64(encodedText));
713        assertEquals(plainText, decodedText);
714    }
715
716    @Test
717    public void testSingletons() {
718        assertEquals("AA==", new String(Base64.encodeBase64(new byte[]{(byte) 0})));
719        assertEquals("AQ==", new String(Base64.encodeBase64(new byte[]{(byte) 1})));
720        assertEquals("Ag==", new String(Base64.encodeBase64(new byte[]{(byte) 2})));
721        assertEquals("Aw==", new String(Base64.encodeBase64(new byte[]{(byte) 3})));
722        assertEquals("BA==", new String(Base64.encodeBase64(new byte[]{(byte) 4})));
723        assertEquals("BQ==", new String(Base64.encodeBase64(new byte[]{(byte) 5})));
724        assertEquals("Bg==", new String(Base64.encodeBase64(new byte[]{(byte) 6})));
725        assertEquals("Bw==", new String(Base64.encodeBase64(new byte[]{(byte) 7})));
726        assertEquals("CA==", new String(Base64.encodeBase64(new byte[]{(byte) 8})));
727        assertEquals("CQ==", new String(Base64.encodeBase64(new byte[]{(byte) 9})));
728        assertEquals("Cg==", new String(Base64.encodeBase64(new byte[]{(byte) 10})));
729        assertEquals("Cw==", new String(Base64.encodeBase64(new byte[]{(byte) 11})));
730        assertEquals("DA==", new String(Base64.encodeBase64(new byte[]{(byte) 12})));
731        assertEquals("DQ==", new String(Base64.encodeBase64(new byte[]{(byte) 13})));
732        assertEquals("Dg==", new String(Base64.encodeBase64(new byte[]{(byte) 14})));
733        assertEquals("Dw==", new String(Base64.encodeBase64(new byte[]{(byte) 15})));
734        assertEquals("EA==", new String(Base64.encodeBase64(new byte[]{(byte) 16})));
735        assertEquals("EQ==", new String(Base64.encodeBase64(new byte[]{(byte) 17})));
736        assertEquals("Eg==", new String(Base64.encodeBase64(new byte[]{(byte) 18})));
737        assertEquals("Ew==", new String(Base64.encodeBase64(new byte[]{(byte) 19})));
738        assertEquals("FA==", new String(Base64.encodeBase64(new byte[]{(byte) 20})));
739        assertEquals("FQ==", new String(Base64.encodeBase64(new byte[]{(byte) 21})));
740        assertEquals("Fg==", new String(Base64.encodeBase64(new byte[]{(byte) 22})));
741        assertEquals("Fw==", new String(Base64.encodeBase64(new byte[]{(byte) 23})));
742        assertEquals("GA==", new String(Base64.encodeBase64(new byte[]{(byte) 24})));
743        assertEquals("GQ==", new String(Base64.encodeBase64(new byte[]{(byte) 25})));
744        assertEquals("Gg==", new String(Base64.encodeBase64(new byte[]{(byte) 26})));
745        assertEquals("Gw==", new String(Base64.encodeBase64(new byte[]{(byte) 27})));
746        assertEquals("HA==", new String(Base64.encodeBase64(new byte[]{(byte) 28})));
747        assertEquals("HQ==", new String(Base64.encodeBase64(new byte[]{(byte) 29})));
748        assertEquals("Hg==", new String(Base64.encodeBase64(new byte[]{(byte) 30})));
749        assertEquals("Hw==", new String(Base64.encodeBase64(new byte[]{(byte) 31})));
750        assertEquals("IA==", new String(Base64.encodeBase64(new byte[]{(byte) 32})));
751        assertEquals("IQ==", new String(Base64.encodeBase64(new byte[]{(byte) 33})));
752        assertEquals("Ig==", new String(Base64.encodeBase64(new byte[]{(byte) 34})));
753        assertEquals("Iw==", new String(Base64.encodeBase64(new byte[]{(byte) 35})));
754        assertEquals("JA==", new String(Base64.encodeBase64(new byte[]{(byte) 36})));
755        assertEquals("JQ==", new String(Base64.encodeBase64(new byte[]{(byte) 37})));
756        assertEquals("Jg==", new String(Base64.encodeBase64(new byte[]{(byte) 38})));
757        assertEquals("Jw==", new String(Base64.encodeBase64(new byte[]{(byte) 39})));
758        assertEquals("KA==", new String(Base64.encodeBase64(new byte[]{(byte) 40})));
759        assertEquals("KQ==", new String(Base64.encodeBase64(new byte[]{(byte) 41})));
760        assertEquals("Kg==", new String(Base64.encodeBase64(new byte[]{(byte) 42})));
761        assertEquals("Kw==", new String(Base64.encodeBase64(new byte[]{(byte) 43})));
762        assertEquals("LA==", new String(Base64.encodeBase64(new byte[]{(byte) 44})));
763        assertEquals("LQ==", new String(Base64.encodeBase64(new byte[]{(byte) 45})));
764        assertEquals("Lg==", new String(Base64.encodeBase64(new byte[]{(byte) 46})));
765        assertEquals("Lw==", new String(Base64.encodeBase64(new byte[]{(byte) 47})));
766        assertEquals("MA==", new String(Base64.encodeBase64(new byte[]{(byte) 48})));
767        assertEquals("MQ==", new String(Base64.encodeBase64(new byte[]{(byte) 49})));
768        assertEquals("Mg==", new String(Base64.encodeBase64(new byte[]{(byte) 50})));
769        assertEquals("Mw==", new String(Base64.encodeBase64(new byte[]{(byte) 51})));
770        assertEquals("NA==", new String(Base64.encodeBase64(new byte[]{(byte) 52})));
771        assertEquals("NQ==", new String(Base64.encodeBase64(new byte[]{(byte) 53})));
772        assertEquals("Ng==", new String(Base64.encodeBase64(new byte[]{(byte) 54})));
773        assertEquals("Nw==", new String(Base64.encodeBase64(new byte[]{(byte) 55})));
774        assertEquals("OA==", new String(Base64.encodeBase64(new byte[]{(byte) 56})));
775        assertEquals("OQ==", new String(Base64.encodeBase64(new byte[]{(byte) 57})));
776        assertEquals("Og==", new String(Base64.encodeBase64(new byte[]{(byte) 58})));
777        assertEquals("Ow==", new String(Base64.encodeBase64(new byte[]{(byte) 59})));
778        assertEquals("PA==", new String(Base64.encodeBase64(new byte[]{(byte) 60})));
779        assertEquals("PQ==", new String(Base64.encodeBase64(new byte[]{(byte) 61})));
780        assertEquals("Pg==", new String(Base64.encodeBase64(new byte[]{(byte) 62})));
781        assertEquals("Pw==", new String(Base64.encodeBase64(new byte[]{(byte) 63})));
782        assertEquals("QA==", new String(Base64.encodeBase64(new byte[]{(byte) 64})));
783        assertEquals("QQ==", new String(Base64.encodeBase64(new byte[]{(byte) 65})));
784        assertEquals("Qg==", new String(Base64.encodeBase64(new byte[]{(byte) 66})));
785        assertEquals("Qw==", new String(Base64.encodeBase64(new byte[]{(byte) 67})));
786        assertEquals("RA==", new String(Base64.encodeBase64(new byte[]{(byte) 68})));
787        assertEquals("RQ==", new String(Base64.encodeBase64(new byte[]{(byte) 69})));
788        assertEquals("Rg==", new String(Base64.encodeBase64(new byte[]{(byte) 70})));
789        assertEquals("Rw==", new String(Base64.encodeBase64(new byte[]{(byte) 71})));
790        assertEquals("SA==", new String(Base64.encodeBase64(new byte[]{(byte) 72})));
791        assertEquals("SQ==", new String(Base64.encodeBase64(new byte[]{(byte) 73})));
792        assertEquals("Sg==", new String(Base64.encodeBase64(new byte[]{(byte) 74})));
793        assertEquals("Sw==", new String(Base64.encodeBase64(new byte[]{(byte) 75})));
794        assertEquals("TA==", new String(Base64.encodeBase64(new byte[]{(byte) 76})));
795        assertEquals("TQ==", new String(Base64.encodeBase64(new byte[]{(byte) 77})));
796        assertEquals("Tg==", new String(Base64.encodeBase64(new byte[]{(byte) 78})));
797        assertEquals("Tw==", new String(Base64.encodeBase64(new byte[]{(byte) 79})));
798        assertEquals("UA==", new String(Base64.encodeBase64(new byte[]{(byte) 80})));
799        assertEquals("UQ==", new String(Base64.encodeBase64(new byte[]{(byte) 81})));
800        assertEquals("Ug==", new String(Base64.encodeBase64(new byte[]{(byte) 82})));
801        assertEquals("Uw==", new String(Base64.encodeBase64(new byte[]{(byte) 83})));
802        assertEquals("VA==", new String(Base64.encodeBase64(new byte[]{(byte) 84})));
803        assertEquals("VQ==", new String(Base64.encodeBase64(new byte[]{(byte) 85})));
804        assertEquals("Vg==", new String(Base64.encodeBase64(new byte[]{(byte) 86})));
805        assertEquals("Vw==", new String(Base64.encodeBase64(new byte[]{(byte) 87})));
806        assertEquals("WA==", new String(Base64.encodeBase64(new byte[]{(byte) 88})));
807        assertEquals("WQ==", new String(Base64.encodeBase64(new byte[]{(byte) 89})));
808        assertEquals("Wg==", new String(Base64.encodeBase64(new byte[]{(byte) 90})));
809        assertEquals("Ww==", new String(Base64.encodeBase64(new byte[]{(byte) 91})));
810        assertEquals("XA==", new String(Base64.encodeBase64(new byte[]{(byte) 92})));
811        assertEquals("XQ==", new String(Base64.encodeBase64(new byte[]{(byte) 93})));
812        assertEquals("Xg==", new String(Base64.encodeBase64(new byte[]{(byte) 94})));
813        assertEquals("Xw==", new String(Base64.encodeBase64(new byte[]{(byte) 95})));
814        assertEquals("YA==", new String(Base64.encodeBase64(new byte[]{(byte) 96})));
815        assertEquals("YQ==", new String(Base64.encodeBase64(new byte[]{(byte) 97})));
816        assertEquals("Yg==", new String(Base64.encodeBase64(new byte[]{(byte) 98})));
817        assertEquals("Yw==", new String(Base64.encodeBase64(new byte[]{(byte) 99})));
818        assertEquals("ZA==", new String(Base64.encodeBase64(new byte[]{(byte) 100})));
819        assertEquals("ZQ==", new String(Base64.encodeBase64(new byte[]{(byte) 101})));
820        assertEquals("Zg==", new String(Base64.encodeBase64(new byte[]{(byte) 102})));
821        assertEquals("Zw==", new String(Base64.encodeBase64(new byte[]{(byte) 103})));
822        assertEquals("aA==", new String(Base64.encodeBase64(new byte[]{(byte) 104})));
823        for (int i = -128; i <= 127; i++) {
824            final byte test[] = {(byte) i};
825            assertTrue(Arrays.equals(test, Base64.decodeBase64(Base64.encodeBase64(test))));
826        }
827    }
828
829    @Test
830    public void testSingletonsChunked() {
831        assertEquals("AA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0})));
832        assertEquals("AQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 1})));
833        assertEquals("Ag==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 2})));
834        assertEquals("Aw==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 3})));
835        assertEquals("BA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 4})));
836        assertEquals("BQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 5})));
837        assertEquals("Bg==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 6})));
838        assertEquals("Bw==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 7})));
839        assertEquals("CA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 8})));
840        assertEquals("CQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 9})));
841        assertEquals("Cg==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 10})));
842        assertEquals("Cw==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 11})));
843        assertEquals("DA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 12})));
844        assertEquals("DQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 13})));
845        assertEquals("Dg==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 14})));
846        assertEquals("Dw==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 15})));
847        assertEquals("EA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 16})));
848        assertEquals("EQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 17})));
849        assertEquals("Eg==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 18})));
850        assertEquals("Ew==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 19})));
851        assertEquals("FA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 20})));
852        assertEquals("FQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 21})));
853        assertEquals("Fg==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 22})));
854        assertEquals("Fw==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 23})));
855        assertEquals("GA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 24})));
856        assertEquals("GQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 25})));
857        assertEquals("Gg==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 26})));
858        assertEquals("Gw==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 27})));
859        assertEquals("HA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 28})));
860        assertEquals("HQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 29})));
861        assertEquals("Hg==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 30})));
862        assertEquals("Hw==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 31})));
863        assertEquals("IA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 32})));
864        assertEquals("IQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 33})));
865        assertEquals("Ig==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 34})));
866        assertEquals("Iw==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 35})));
867        assertEquals("JA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 36})));
868        assertEquals("JQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 37})));
869        assertEquals("Jg==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 38})));
870        assertEquals("Jw==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 39})));
871        assertEquals("KA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 40})));
872        assertEquals("KQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 41})));
873        assertEquals("Kg==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 42})));
874        assertEquals("Kw==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 43})));
875        assertEquals("LA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 44})));
876        assertEquals("LQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 45})));
877        assertEquals("Lg==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 46})));
878        assertEquals("Lw==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 47})));
879        assertEquals("MA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 48})));
880        assertEquals("MQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 49})));
881        assertEquals("Mg==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 50})));
882        assertEquals("Mw==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 51})));
883        assertEquals("NA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 52})));
884        assertEquals("NQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 53})));
885        assertEquals("Ng==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 54})));
886        assertEquals("Nw==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 55})));
887        assertEquals("OA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 56})));
888        assertEquals("OQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 57})));
889        assertEquals("Og==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 58})));
890        assertEquals("Ow==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 59})));
891        assertEquals("PA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 60})));
892        assertEquals("PQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 61})));
893        assertEquals("Pg==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 62})));
894        assertEquals("Pw==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 63})));
895        assertEquals("QA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 64})));
896        assertEquals("QQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 65})));
897        assertEquals("Qg==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 66})));
898        assertEquals("Qw==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 67})));
899        assertEquals("RA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 68})));
900        assertEquals("RQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 69})));
901        assertEquals("Rg==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 70})));
902        assertEquals("Rw==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 71})));
903        assertEquals("SA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 72})));
904        assertEquals("SQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 73})));
905        assertEquals("Sg==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 74})));
906        assertEquals("Sw==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 75})));
907        assertEquals("TA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 76})));
908        assertEquals("TQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 77})));
909        assertEquals("Tg==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 78})));
910        assertEquals("Tw==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 79})));
911        assertEquals("UA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 80})));
912        assertEquals("UQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 81})));
913        assertEquals("Ug==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 82})));
914        assertEquals("Uw==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 83})));
915        assertEquals("VA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 84})));
916        assertEquals("VQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 85})));
917        assertEquals("Vg==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 86})));
918        assertEquals("Vw==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 87})));
919        assertEquals("WA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 88})));
920        assertEquals("WQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 89})));
921        assertEquals("Wg==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 90})));
922        assertEquals("Ww==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 91})));
923        assertEquals("XA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 92})));
924        assertEquals("XQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 93})));
925        assertEquals("Xg==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 94})));
926        assertEquals("Xw==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 95})));
927        assertEquals("YA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 96})));
928        assertEquals("YQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 97})));
929        assertEquals("Yg==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 98})));
930        assertEquals("Yw==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 99})));
931        assertEquals("ZA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 100})));
932        assertEquals("ZQ==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 101})));
933        assertEquals("Zg==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 102})));
934        assertEquals("Zw==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 103})));
935        assertEquals("aA==\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 104})));
936    }
937
938    @Test
939    public void testTriplets() {
940        assertEquals("AAAA", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 0})));
941        assertEquals("AAAB", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 1})));
942        assertEquals("AAAC", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 2})));
943        assertEquals("AAAD", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 3})));
944        assertEquals("AAAE", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 4})));
945        assertEquals("AAAF", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 5})));
946        assertEquals("AAAG", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 6})));
947        assertEquals("AAAH", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 7})));
948        assertEquals("AAAI", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 8})));
949        assertEquals("AAAJ", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 9})));
950        assertEquals("AAAK", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 10})));
951        assertEquals("AAAL", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 11})));
952        assertEquals("AAAM", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 12})));
953        assertEquals("AAAN", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 13})));
954        assertEquals("AAAO", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 14})));
955        assertEquals("AAAP", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 15})));
956        assertEquals("AAAQ", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 16})));
957        assertEquals("AAAR", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 17})));
958        assertEquals("AAAS", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 18})));
959        assertEquals("AAAT", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 19})));
960        assertEquals("AAAU", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 20})));
961        assertEquals("AAAV", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 21})));
962        assertEquals("AAAW", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 22})));
963        assertEquals("AAAX", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 23})));
964        assertEquals("AAAY", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 24})));
965        assertEquals("AAAZ", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 25})));
966        assertEquals("AAAa", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 26})));
967        assertEquals("AAAb", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 27})));
968        assertEquals("AAAc", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 28})));
969        assertEquals("AAAd", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 29})));
970        assertEquals("AAAe", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 30})));
971        assertEquals("AAAf", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 31})));
972        assertEquals("AAAg", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 32})));
973        assertEquals("AAAh", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 33})));
974        assertEquals("AAAi", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 34})));
975        assertEquals("AAAj", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 35})));
976        assertEquals("AAAk", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 36})));
977        assertEquals("AAAl", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 37})));
978        assertEquals("AAAm", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 38})));
979        assertEquals("AAAn", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 39})));
980        assertEquals("AAAo", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 40})));
981        assertEquals("AAAp", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 41})));
982        assertEquals("AAAq", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 42})));
983        assertEquals("AAAr", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 43})));
984        assertEquals("AAAs", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 44})));
985        assertEquals("AAAt", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 45})));
986        assertEquals("AAAu", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 46})));
987        assertEquals("AAAv", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 47})));
988        assertEquals("AAAw", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 48})));
989        assertEquals("AAAx", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 49})));
990        assertEquals("AAAy", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 50})));
991        assertEquals("AAAz", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 51})));
992        assertEquals("AAA0", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 52})));
993        assertEquals("AAA1", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 53})));
994        assertEquals("AAA2", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 54})));
995        assertEquals("AAA3", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 55})));
996        assertEquals("AAA4", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 56})));
997        assertEquals("AAA5", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 57})));
998        assertEquals("AAA6", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 58})));
999        assertEquals("AAA7", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 59})));
1000        assertEquals("AAA8", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 60})));
1001        assertEquals("AAA9", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 61})));
1002        assertEquals("AAA+", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 62})));
1003        assertEquals("AAA/", new String(Base64.encodeBase64(new byte[]{(byte) 0, (byte) 0, (byte) 63})));
1004    }
1005
1006    @Test
1007    public void testTripletsChunked() {
1008        assertEquals("AAAA\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 0})));
1009        assertEquals("AAAB\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 1})));
1010        assertEquals("AAAC\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 2})));
1011        assertEquals("AAAD\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 3})));
1012        assertEquals("AAAE\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 4})));
1013        assertEquals("AAAF\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 5})));
1014        assertEquals("AAAG\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 6})));
1015        assertEquals("AAAH\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 7})));
1016        assertEquals("AAAI\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 8})));
1017        assertEquals("AAAJ\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 9})));
1018        assertEquals("AAAK\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 10})));
1019        assertEquals("AAAL\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 11})));
1020        assertEquals("AAAM\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 12})));
1021        assertEquals("AAAN\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 13})));
1022        assertEquals("AAAO\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 14})));
1023        assertEquals("AAAP\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 15})));
1024        assertEquals("AAAQ\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 16})));
1025        assertEquals("AAAR\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 17})));
1026        assertEquals("AAAS\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 18})));
1027        assertEquals("AAAT\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 19})));
1028        assertEquals("AAAU\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 20})));
1029        assertEquals("AAAV\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 21})));
1030        assertEquals("AAAW\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 22})));
1031        assertEquals("AAAX\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 23})));
1032        assertEquals("AAAY\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 24})));
1033        assertEquals("AAAZ\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 25})));
1034        assertEquals("AAAa\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 26})));
1035        assertEquals("AAAb\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 27})));
1036        assertEquals("AAAc\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 28})));
1037        assertEquals("AAAd\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 29})));
1038        assertEquals("AAAe\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 30})));
1039        assertEquals("AAAf\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 31})));
1040        assertEquals("AAAg\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 32})));
1041        assertEquals("AAAh\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 33})));
1042        assertEquals("AAAi\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 34})));
1043        assertEquals("AAAj\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 35})));
1044        assertEquals("AAAk\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 36})));
1045        assertEquals("AAAl\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 37})));
1046        assertEquals("AAAm\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 38})));
1047        assertEquals("AAAn\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 39})));
1048        assertEquals("AAAo\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 40})));
1049        assertEquals("AAAp\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 41})));
1050        assertEquals("AAAq\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 42})));
1051        assertEquals("AAAr\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 43})));
1052        assertEquals("AAAs\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 44})));
1053        assertEquals("AAAt\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 45})));
1054        assertEquals("AAAu\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 46})));
1055        assertEquals("AAAv\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 47})));
1056        assertEquals("AAAw\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 48})));
1057        assertEquals("AAAx\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 49})));
1058        assertEquals("AAAy\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 50})));
1059        assertEquals("AAAz\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 51})));
1060        assertEquals("AAA0\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 52})));
1061        assertEquals("AAA1\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 53})));
1062        assertEquals("AAA2\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 54})));
1063        assertEquals("AAA3\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 55})));
1064        assertEquals("AAA4\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 56})));
1065        assertEquals("AAA5\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 57})));
1066        assertEquals("AAA6\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 58})));
1067        assertEquals("AAA7\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 59})));
1068        assertEquals("AAA8\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 60})));
1069        assertEquals("AAA9\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 61})));
1070        assertEquals("AAA+\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 62})));
1071        assertEquals("AAA/\r\n", new String(Base64.encodeBase64Chunked(new byte[]{(byte) 0, (byte) 0, (byte) 63})));
1072    }
1073
1074    /**
1075     * Tests url-safe Base64 against random data, sizes 0 to 150.
1076     */
1077    @Test
1078    public void testUrlSafe() {
1079        // test random data of sizes 0 thru 150
1080        for (int i = 0; i <= 150; i++) {
1081            final byte[][] randomData = Base64TestData.randomData(i, true);
1082            final byte[] encoded = randomData[1];
1083            final byte[] decoded = randomData[0];
1084            final byte[] result = Base64.decodeBase64(encoded);
1085            assertTrue("url-safe i=" + i, Arrays.equals(decoded, result));
1086            assertFalse("url-safe i=" + i + " no '='", Base64TestData.bytesContain(encoded, (byte) '='));
1087            assertFalse("url-safe i=" + i + " no '\\'", Base64TestData.bytesContain(encoded, (byte) '\\'));
1088            assertFalse("url-safe i=" + i + " no '+'", Base64TestData.bytesContain(encoded, (byte) '+'));
1089        }
1090
1091    }
1092
1093    /**
1094     * Base64 encoding of UUID's is a common use-case, especially in URL-SAFE mode. This test case ends up being the
1095     * "URL-SAFE" JUnit's.
1096     *
1097     * @throws DecoderException
1098     *             if Hex.decode() fails - a serious problem since Hex comes from our own commons-codec!
1099     */
1100    @Test
1101    public void testUUID() throws DecoderException {
1102        // The 4 UUID's below contains mixtures of + and / to help us test the
1103        // URL-SAFE encoding mode.
1104        final byte[][] ids = new byte[4][];
1105
1106        // ids[0] was chosen so that it encodes with at least one +.
1107        ids[0] = Hex.decodeHex("94ed8d0319e4493399560fb67404d370".toCharArray());
1108
1109        // ids[1] was chosen so that it encodes with both / and +.
1110        ids[1] = Hex.decodeHex("2bf7cc2701fe4397b49ebeed5acc7090".toCharArray());
1111
1112        // ids[2] was chosen so that it encodes with at least one /.
1113        ids[2] = Hex.decodeHex("64be154b6ffa40258d1a01288e7c31ca".toCharArray());
1114
1115        // ids[3] was chosen so that it encodes with both / and +, with /
1116        // right at the beginning.
1117        ids[3] = Hex.decodeHex("ff7f8fc01cdb471a8c8b5a9306183fe8".toCharArray());
1118
1119        final byte[][] standard = new byte[4][];
1120        standard[0] = StringUtils.getBytesUtf8("lO2NAxnkSTOZVg+2dATTcA==");
1121        standard[1] = StringUtils.getBytesUtf8("K/fMJwH+Q5e0nr7tWsxwkA==");
1122        standard[2] = StringUtils.getBytesUtf8("ZL4VS2/6QCWNGgEojnwxyg==");
1123        standard[3] = StringUtils.getBytesUtf8("/3+PwBzbRxqMi1qTBhg/6A==");
1124
1125        final byte[][] urlSafe1 = new byte[4][];
1126        // regular padding (two '==' signs).
1127        urlSafe1[0] = StringUtils.getBytesUtf8("lO2NAxnkSTOZVg-2dATTcA==");
1128        urlSafe1[1] = StringUtils.getBytesUtf8("K_fMJwH-Q5e0nr7tWsxwkA==");
1129        urlSafe1[2] = StringUtils.getBytesUtf8("ZL4VS2_6QCWNGgEojnwxyg==");
1130        urlSafe1[3] = StringUtils.getBytesUtf8("_3-PwBzbRxqMi1qTBhg_6A==");
1131
1132        final byte[][] urlSafe2 = new byte[4][];
1133        // single padding (only one '=' sign).
1134        urlSafe2[0] = StringUtils.getBytesUtf8("lO2NAxnkSTOZVg-2dATTcA=");
1135        urlSafe2[1] = StringUtils.getBytesUtf8("K_fMJwH-Q5e0nr7tWsxwkA=");
1136        urlSafe2[2] = StringUtils.getBytesUtf8("ZL4VS2_6QCWNGgEojnwxyg=");
1137        urlSafe2[3] = StringUtils.getBytesUtf8("_3-PwBzbRxqMi1qTBhg_6A=");
1138
1139        final byte[][] urlSafe3 = new byte[4][];
1140        // no padding (no '=' signs).
1141        urlSafe3[0] = StringUtils.getBytesUtf8("lO2NAxnkSTOZVg-2dATTcA");
1142        urlSafe3[1] = StringUtils.getBytesUtf8("K_fMJwH-Q5e0nr7tWsxwkA");
1143        urlSafe3[2] = StringUtils.getBytesUtf8("ZL4VS2_6QCWNGgEojnwxyg");
1144        urlSafe3[3] = StringUtils.getBytesUtf8("_3-PwBzbRxqMi1qTBhg_6A");
1145
1146        for (int i = 0; i < 4; i++) {
1147            final byte[] encodedStandard = Base64.encodeBase64(ids[i]);
1148            final byte[] encodedUrlSafe = Base64.encodeBase64URLSafe(ids[i]);
1149            final byte[] decodedStandard = Base64.decodeBase64(standard[i]);
1150            final byte[] decodedUrlSafe1 = Base64.decodeBase64(urlSafe1[i]);
1151            final byte[] decodedUrlSafe2 = Base64.decodeBase64(urlSafe2[i]);
1152            final byte[] decodedUrlSafe3 = Base64.decodeBase64(urlSafe3[i]);
1153
1154            // Very important debugging output should anyone
1155            // ever need to delve closely into this stuff.
1156            if (false) {
1157                System.out.println("reference: [" + Hex.encodeHexString(ids[i]) + "]");
1158                System.out.println("standard:  [" +
1159                        Hex.encodeHexString(decodedStandard) +
1160                    "] From: [" +
1161                    StringUtils.newStringUtf8(standard[i]) +
1162                    "]");
1163                System.out.println("safe1:     [" +
1164                        Hex.encodeHexString(decodedUrlSafe1) +
1165                    "] From: [" +
1166                    StringUtils.newStringUtf8(urlSafe1[i]) +
1167                    "]");
1168                System.out.println("safe2:     [" +
1169                        Hex.encodeHexString(decodedUrlSafe2) +
1170                    "] From: [" +
1171                    StringUtils.newStringUtf8(urlSafe2[i]) +
1172                    "]");
1173                System.out.println("safe3:     [" +
1174                        Hex.encodeHexString(decodedUrlSafe3) +
1175                    "] From: [" +
1176                    StringUtils.newStringUtf8(urlSafe3[i]) +
1177                    "]");
1178            }
1179
1180            assertTrue("standard encode uuid", Arrays.equals(encodedStandard, standard[i]));
1181            assertTrue("url-safe encode uuid", Arrays.equals(encodedUrlSafe, urlSafe3[i]));
1182            assertTrue("standard decode uuid", Arrays.equals(decodedStandard, ids[i]));
1183            assertTrue("url-safe1 decode uuid", Arrays.equals(decodedUrlSafe1, ids[i]));
1184            assertTrue("url-safe2 decode uuid", Arrays.equals(decodedUrlSafe2, ids[i]));
1185            assertTrue("url-safe3 decode uuid", Arrays.equals(decodedUrlSafe3, ids[i]));
1186        }
1187    }
1188
1189    @Test
1190    public void testByteToStringVariations() throws DecoderException {
1191        final Base64 base64 = new Base64(0);
1192        final byte[] b1 = StringUtils.getBytesUtf8("Hello World");
1193        final byte[] b2 = new byte[0];
1194        final byte[] b3 = null;
1195        final byte[] b4 = Hex.decodeHex("2bf7cc2701fe4397b49ebeed5acc7090".toCharArray());  // for url-safe tests
1196
1197        assertEquals("byteToString Hello World", "SGVsbG8gV29ybGQ=", base64.encodeToString(b1));
1198        assertEquals("byteToString static Hello World", "SGVsbG8gV29ybGQ=", Base64.encodeBase64String(b1));
1199        assertEquals("byteToString \"\"", "", base64.encodeToString(b2));
1200        assertEquals("byteToString static \"\"", "", Base64.encodeBase64String(b2));
1201        assertEquals("byteToString null", null, base64.encodeToString(b3));
1202        assertEquals("byteToString static null", null, Base64.encodeBase64String(b3));
1203        assertEquals("byteToString UUID", "K/fMJwH+Q5e0nr7tWsxwkA==", base64.encodeToString(b4));
1204        assertEquals("byteToString static UUID", "K/fMJwH+Q5e0nr7tWsxwkA==", Base64.encodeBase64String(b4));
1205        assertEquals("byteToString static-url-safe UUID", "K_fMJwH-Q5e0nr7tWsxwkA", Base64.encodeBase64URLSafeString(b4));
1206    }
1207
1208    @Test
1209    public void testStringToByteVariations() throws DecoderException {
1210        final Base64 base64 = new Base64();
1211        final String s1 = "SGVsbG8gV29ybGQ=\r\n";
1212        final String s2 = "";
1213        final String s3 = null;
1214        final String s4a = "K/fMJwH+Q5e0nr7tWsxwkA==\r\n";
1215        final String s4b = "K_fMJwH-Q5e0nr7tWsxwkA";
1216        final byte[] b4 = Hex.decodeHex("2bf7cc2701fe4397b49ebeed5acc7090".toCharArray());  // for url-safe tests
1217
1218        assertEquals("StringToByte Hello World", "Hello World", StringUtils.newStringUtf8(base64.decode(s1)));
1219        assertEquals("StringToByte Hello World", "Hello World", StringUtils.newStringUtf8((byte[])base64.decode((Object)s1)));
1220        assertEquals("StringToByte static Hello World", "Hello World", StringUtils.newStringUtf8(Base64.decodeBase64(s1)));
1221        assertEquals("StringToByte \"\"", "", StringUtils.newStringUtf8(base64.decode(s2)));
1222        assertEquals("StringToByte static \"\"", "", StringUtils.newStringUtf8(Base64.decodeBase64(s2)));
1223        assertEquals("StringToByte null", null, StringUtils.newStringUtf8(base64.decode(s3)));
1224        assertEquals("StringToByte static null", null, StringUtils.newStringUtf8(Base64.decodeBase64(s3)));
1225        assertTrue("StringToByte UUID", Arrays.equals(b4, base64.decode(s4b)));
1226        assertTrue("StringToByte static UUID", Arrays.equals(b4, Base64.decodeBase64(s4a)));
1227        assertTrue("StringToByte static-url-safe UUID", Arrays.equals(b4, Base64.decodeBase64(s4b)));
1228    }
1229
1230    private String toString(final byte[] data) {
1231        final StringBuilder buf = new StringBuilder();
1232        for (int i = 0; i < data.length; i++) {
1233            buf.append(data[i]);
1234            if (i != data.length - 1) {
1235                buf.append(",");
1236            }
1237        }
1238        return buf.toString();
1239    }
1240
1241    /**
1242     * Tests a lineSeparator much bigger than DEFAULT_BUFFER_SIZE.
1243     *
1244     * @see "<a href='http://mail-archives.apache.org/mod_mbox/commons-dev/201202.mbox/%3C4F3C85D7.5060706@snafu.de%3E'>dev@commons.apache.org</a>"
1245     */
1246    @Test
1247    @Ignore
1248    public void testHugeLineSeparator() {
1249        final int BaseNCodec_DEFAULT_BUFFER_SIZE = 8192;
1250        final int Base64_BYTES_PER_ENCODED_BLOCK = 4;
1251        final byte[] baLineSeparator = new byte[BaseNCodec_DEFAULT_BUFFER_SIZE * 4 - 3];
1252        final Base64 b64 = new Base64(Base64_BYTES_PER_ENCODED_BLOCK, baLineSeparator);
1253        final String strOriginal = "Hello World";
1254        final String strDecoded = new String(b64.decode(b64.encode(StringUtils.getBytesUtf8(strOriginal))));
1255        assertEquals("testDEFAULT_BUFFER_SIZE", strOriginal, strDecoded);
1256    }
1257
1258}