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.util.Arrays;
28  import java.util.Random;
29  
30  import org.apache.commons.codec.Charsets;
31  import org.apache.commons.codec.DecoderException;
32  import org.apache.commons.codec.EncoderException;
33  import org.junit.Ignore;
34  import org.junit.Test;
35  
36  /**
37   * Test cases for Base64 class.
38   *
39   * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>
40   * @version $Id: Base64Test.html 889935 2013-12-11 05:05:13Z ggregory $
41   */
42  public class Base64Test {
43  
44      private final Random random = new Random();
45  
46      /**
47       * @return Returns the random.
48       */
49      public Random getRandom() {
50          return this.random;
51      }
52  
53      /**
54       * Test the isStringBase64 method.
55       */
56      @Test
57      public void testIsStringBase64() {
58          final String nullString = null;
59          final String emptyString = "";
60          final String validString = "abc===defg\n\r123456\r789\r\rABC\n\nDEF==GHI\r\nJKL==============";
61          final String invalidString = validString + (char)0; // append null character
62  
63          try {
64              Base64.isBase64(nullString);
65              fail("Base64.isStringBase64() should not be null-safe.");
66          } catch (final NullPointerException npe) {
67              assertNotNull("Base64.isStringBase64() should not be null-safe.", npe);
68          }
69  
70          assertTrue("Base64.isStringBase64(empty-string) is true", Base64.isBase64(emptyString));
71          assertTrue("Base64.isStringBase64(valid-string) is true", Base64.isBase64(validString));
72          assertFalse("Base64.isStringBase64(invalid-string) is false", Base64.isBase64(invalidString));
73      }
74  
75      /**
76       * Test the Base64 implementation
77       */
78      @Test
79      public void testBase64() {
80          final String content = "Hello World";
81          String encodedContent;
82          byte[] encodedBytes = Base64.encodeBase64(StringUtils.getBytesUtf8(content));
83          encodedContent = StringUtils.newStringUtf8(encodedBytes);
84          assertEquals("encoding hello world", "SGVsbG8gV29ybGQ=", encodedContent);
85  
86          Base64 b64 = new Base64(BaseNCodec.MIME_CHUNK_SIZE, null);  // null lineSeparator same as saying no-chunking
87          encodedBytes = b64.encode(StringUtils.getBytesUtf8(content));
88          encodedContent = StringUtils.newStringUtf8(encodedBytes);
89          assertEquals("encoding hello world", "SGVsbG8gV29ybGQ=", encodedContent);
90  
91          b64 = new Base64(0, null);  // null lineSeparator same as saying no-chunking
92          encodedBytes = b64.encode(StringUtils.getBytesUtf8(content));
93          encodedContent = StringUtils.newStringUtf8(encodedBytes);
94          assertEquals("encoding hello world", "SGVsbG8gV29ybGQ=", encodedContent);
95  
96          // bogus characters to decode (to skip actually) {e-acute*6}
97          final byte[] decode = b64.decode("SGVsbG{\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9}8gV29ybGQ=");
98          final String decodeString = StringUtils.newStringUtf8(decode);
99          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 }