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