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    
018    package org.apache.commons.codec.binary;
019    
020    import static org.junit.Assert.assertEquals;
021    import static org.junit.Assert.assertFalse;
022    import static org.junit.Assert.assertNotNull;
023    import static org.junit.Assert.assertTrue;
024    import static org.junit.Assert.fail;
025    
026    import java.math.BigInteger;
027    import java.util.Arrays;
028    import java.util.Random;
029    
030    import org.apache.commons.codec.Charsets;
031    import org.apache.commons.codec.DecoderException;
032    import org.apache.commons.codec.EncoderException;
033    import org.junit.Ignore;
034    import 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 889935 2013-12-11 05:05:13Z ggregory $
041     */
042    public 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            byte[] result = Base64.decodeBase64(content);
118            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    }