1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.codec.binary;
19
20 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertFalse;
23 import static org.junit.jupiter.api.Assertions.assertNotNull;
24 import static org.junit.jupiter.api.Assertions.assertNull;
25 import static org.junit.jupiter.api.Assertions.assertThrows;
26 import static org.junit.jupiter.api.Assertions.assertTrue;
27
28 import java.nio.charset.Charset;
29 import java.nio.charset.StandardCharsets;
30 import java.util.Arrays;
31 import java.util.stream.IntStream;
32
33 import org.apache.commons.codec.CodecPolicy;
34 import org.apache.commons.codec.DecoderException;
35 import org.apache.commons.lang3.ArrayUtils;
36 import org.junit.jupiter.api.Test;
37 import org.junit.jupiter.params.ParameterizedTest;
38 import org.junit.jupiter.params.provider.MethodSource;
39
40
41
42
43 class Base32Test {
44
45 private static final Charset CHARSET_UTF8 = StandardCharsets.UTF_8;
46
47
48
49 private static final String [][] BASE32_TEST_CASES = {
50 { "" , "" },
51 { "f" , "MY======" },
52 { "fo" , "MZXQ====" },
53 { "foo" , "MZXW6===" },
54 { "foob" , "MZXW6YQ=" },
55 { "fooba" , "MZXW6YTB" },
56 { "foobar" , "MZXW6YTBOI======" }
57 };
58
59
60
61
62
63
64
65 static final String[] BASE32_IMPOSSIBLE_CASES = {
66 "MC======",
67 "MZXE====",
68 "MZXWB===",
69 "MZXW6YB=",
70 "MZXW6YTBOC======",
71 "AB======"
72 };
73
74
75
76 private static final String[] BASE32_IMPOSSIBLE_CASES_CHUNKED = {
77 "M2======\r\n",
78 "MZX0====\r\n",
79 "MZXW0===\r\n",
80 "MZXW6Y2=\r\n",
81 "MZXW6YTBO2======\r\n"
82 };
83
84
85
86 private static final String[] BASE32HEX_IMPOSSIBLE_CASES = {
87 "C2======",
88 "CPN4====",
89 "CPNM1===",
90 "CPNMUO1=",
91 "CPNMUOJ1E2======"
92 };
93
94
95
96
97
98
99
100 private static final byte[] ENCODE_TABLE = {
101 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
102 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
103 '2', '3', '4', '5', '6', '7'
104 };
105
106
107 private static final Object[][] BASE32_BINARY_TEST_CASES;
108
109
110
111
112 static {
113 final Hex hex = new Hex();
114 try {
115 BASE32_BINARY_TEST_CASES = new Object[][] {
116 new Object[] { hex.decode("623a01735836e9a126e12fbf95e013ee6892997c"),
117 "MI5AC42YG3U2CJXBF67ZLYAT5ZUJFGL4" },
118 new Object[] { hex.decode("623a01735836e9a126e12fbf95e013ee6892997c"),
119 "mi5ac42yg3u2cjxbf67zlyat5zujfgl4" },
120 new Object[] { hex.decode("739ce42108"),
121 "OOOOIIII" }
122 };
123 } catch (final DecoderException de) {
124 throw new AssertionError(":(", de);
125 }
126 }
127
128
129 private static final String [][] BASE32HEX_TEST_CASES = {
130 { "" , "" },
131 { "f" , "CO======" },
132 { "fo" , "CPNG====" },
133 { "foo" , "CPNMU===" },
134 { "foob" , "CPNMUOG=" },
135 { "fooba" , "CPNMUOJ1" },
136 { "foobar" , "CPNMUOJ1E8======" }
137 };
138
139
140
141 private static final String [][] BASE32_TEST_CASES_CHUNKED = {
142 { "" , "" },
143 { "f" , "MY======\r\n" },
144 { "fo" , "MZXQ====\r\n" },
145 { "foo" , "MZXW6===\r\n" },
146 { "foob" , "MZXW6YQ=\r\n" },
147 { "fooba" , "MZXW6YTB\r\n" },
148 { "foobar" , "MZXW6YTBOI======\r\n" }
149 };
150
151
152
153 private static final String [][] BASE32_PAD_TEST_CASES = {
154 { "" , "" },
155 { "f" , "MY%%%%%%" },
156 { "fo" , "MZXQ%%%%" },
157 { "foo" , "MZXW6%%%" },
158 { "foob" , "MZXW6YQ%" },
159 { "fooba" , "MZXW6YTB" },
160 { "foobar" , "MZXW6YTBOI%%%%%%" }
161 };
162
163
164
165
166
167
168
169
170
171
172 private static void assertBase32DecodingOfTrailingBits(final int nbits) {
173
174 final Base32 codec = new Base32(0, null, false, BaseNCodec.PAD_DEFAULT, CodecPolicy.STRICT);
175 assertTrue(codec.isStrictDecoding());
176 assertEquals(CodecPolicy.STRICT, codec.getCodecPolicy());
177
178 final Base32 defaultCodec = new Base32();
179 assertFalse(defaultCodec.isStrictDecoding());
180 assertEquals(CodecPolicy.LENIENT, defaultCodec.getCodecPolicy());
181
182
183
184 final int length = nbits / 5;
185 final byte[] encoded = new byte[8];
186 Arrays.fill(encoded, 0, length, ENCODE_TABLE[0]);
187 Arrays.fill(encoded, length, encoded.length, (byte) '=');
188
189 final int discard = nbits % 8;
190 final int emptyBitsMask = (1 << discard) - 1;
191
192 final boolean invalid = length == 1 || length == 3 || length == 6;
193
194 final int last = length - 1;
195 for (int i = 0; i < 32; i++) {
196 encoded[last] = ENCODE_TABLE[i];
197
198
199 if (invalid || (i & emptyBitsMask) != 0) {
200 assertThrows(IllegalArgumentException.class, () -> codec.decode(encoded), "Final base-32 digit should not be allowed");
201
202 final byte[] decoded = defaultCodec.decode(encoded);
203
204 assertFalse(Arrays.equals(encoded, defaultCodec.encode(decoded)));
205 } else {
206
207 final byte[] decoded = codec.decode(encoded);
208
209 final int bitsEncoded = i >> discard;
210 assertEquals(bitsEncoded, decoded[decoded.length - 1], "Invalid decoding of last character");
211
212 assertArrayEquals(encoded, codec.encode(decoded));
213 }
214 }
215 }
216
217 static IntStream rangeProvider() {
218 return IntStream.range(0, 21);
219 }
220
221 @Test
222 void testBase32AtBufferEnd() {
223 testBase32InBuffer(100, 0);
224 }
225
226 @Test
227 void testBase32AtBufferMiddle() {
228 testBase32InBuffer(100, 100);
229 }
230
231 @Test
232 void testBase32AtBufferStart() {
233 testBase32InBuffer(0, 100);
234 }
235
236 @Test
237 void testBase32BinarySamples() throws Exception {
238 final Base32 codec = new Base32();
239 for (final Object[] element : BASE32_BINARY_TEST_CASES) {
240 final String expected;
241 if (element.length > 2) {
242 expected = (String) element[2];
243 } else {
244 expected = (String) element[1];
245 }
246 assertEquals(expected.toUpperCase(), codec.encodeAsString((byte[]) element[0]));
247 }
248 }
249
250 @Test
251 void testBase32BinarySamplesReverse() throws Exception {
252 final Base32 codec = new Base32();
253 for (final Object[] element : BASE32_BINARY_TEST_CASES) {
254 assertArrayEquals((byte[]) element[0], codec.decode((String) element[1]));
255 }
256 }
257
258 @Test
259 void testBase32Chunked() throws Exception {
260 final Base32 codec = new Base32(20);
261 for (final String[] element : BASE32_TEST_CASES_CHUNKED) {
262 assertEquals(element[1], codec.encodeAsString(element[0].getBytes(CHARSET_UTF8)));
263 }
264 }
265
266 @Test
267 void testBase32DecodingOfTrailing10Bits() {
268 assertBase32DecodingOfTrailingBits(10);
269 }
270
271 @Test
272 void testBase32DecodingOfTrailing15Bits() {
273 assertBase32DecodingOfTrailingBits(15);
274 }
275
276 @Test
277 void testBase32DecodingOfTrailing20Bits() {
278 assertBase32DecodingOfTrailingBits(20);
279 }
280
281 @Test
282 void testBase32DecodingOfTrailing25Bits() {
283 assertBase32DecodingOfTrailingBits(25);
284 }
285
286 @Test
287 void testBase32DecodingOfTrailing30Bits() {
288 assertBase32DecodingOfTrailingBits(30);
289 }
290
291 @Test
292 void testBase32DecodingOfTrailing35Bits() {
293 assertBase32DecodingOfTrailingBits(35);
294 }
295
296 @Test
297 void testBase32DecodingOfTrailing5Bits() {
298 assertBase32DecodingOfTrailingBits(5);
299 }
300
301 @Test
302 void testBase32HexImpossibleSamples() {
303 testImpossibleCases(new Base32(0, null, true, BaseNCodec.PAD_DEFAULT, CodecPolicy.STRICT), BASE32HEX_IMPOSSIBLE_CASES);
304
305 testImpossibleCases(Base32.builder()
306 .setHexEncodeTable(true)
307 .setDecodingPolicy(CodecPolicy.STRICT)
308 .get(), BASE32HEX_IMPOSSIBLE_CASES);
309
310
311
312 testImpossibleCases(Base32.builder()
313 .setHexDecodeTable(false)
314 .setHexDecodeTable(true)
315 .setHexEncodeTable(false)
316 .setHexEncodeTable(true)
317 .setDecodingPolicy(CodecPolicy.STRICT)
318 .get(), BASE32HEX_IMPOSSIBLE_CASES);
319
320 }
321
322 @Test
323 void testBase32HexSamples() throws Exception {
324 final Base32 codec = new Base32(true);
325 for (final String[] element : BASE32HEX_TEST_CASES) {
326 assertEquals(element[1], codec.encodeAsString(element[0].getBytes(CHARSET_UTF8)));
327 }
328 }
329
330 @Test
331 void testBase32HexSamplesReverse() throws Exception {
332 final Base32 codec = new Base32(true);
333 for (final String[] element : BASE32HEX_TEST_CASES) {
334 assertEquals(element[0], new String(codec.decode(element[1]), CHARSET_UTF8));
335 }
336 }
337
338 @Test
339 void testBase32HexSamplesReverseLowercase() throws Exception {
340 final Base32 codec = new Base32(true);
341 for (final String[] element : BASE32HEX_TEST_CASES) {
342 assertEquals(element[0], new String(codec.decode(element[1].toLowerCase()), CHARSET_UTF8));
343 }
344 }
345
346 @Test
347 void testBase32ImpossibleChunked() {
348 testImpossibleCases(new Base32(20, BaseNCodec.CHUNK_SEPARATOR, false, BaseNCodec.PAD_DEFAULT, CodecPolicy.STRICT), BASE32_IMPOSSIBLE_CASES_CHUNKED);
349 }
350
351 @Test
352 void testBase32ImpossibleSamples() {
353 testImpossibleCases(new Base32(0, null, false, BaseNCodec.PAD_DEFAULT, CodecPolicy.STRICT), BASE32_IMPOSSIBLE_CASES);
354 }
355
356 private void testBase32InBuffer(final int startPasSize, final int endPadSize) {
357 final Base32 codec = new Base32();
358 for (final String[] element : BASE32_TEST_CASES) {
359 final byte[] bytes = element[0].getBytes(CHARSET_UTF8);
360 byte[] buffer = ArrayUtils.addAll(bytes, new byte[endPadSize]);
361 buffer = ArrayUtils.addAll(new byte[startPasSize], buffer);
362 assertEquals(element[1], StringUtils.newStringUtf8(codec.encode(buffer, startPasSize, bytes.length)));
363 }
364 }
365
366 @Test
367 void testBase32Samples() throws Exception {
368 final Base32 codec = new Base32();
369 for (final String[] element : BASE32_TEST_CASES) {
370 assertEquals(element[1], codec.encodeAsString(element[0].getBytes(CHARSET_UTF8)));
371 }
372 }
373
374 @Test
375 void testBase32SamplesNonDefaultPadding() throws Exception {
376 final Base32 codec = new Base32((byte) 0x25);
377
378 for (final String[] element : BASE32_PAD_TEST_CASES) {
379 assertEquals(element[1], codec.encodeAsString(element[0].getBytes(CHARSET_UTF8)));
380 }
381 }
382
383 @Test
384 void testBuilderCodecPolicy() {
385 assertEquals(CodecPolicy.LENIENT, Base32.builder().get().getCodecPolicy());
386 assertEquals(CodecPolicy.LENIENT, Base32.builder().setDecodingPolicy(CodecPolicy.LENIENT).get().getCodecPolicy());
387 assertEquals(CodecPolicy.STRICT, Base32.builder().setDecodingPolicy(CodecPolicy.STRICT).get().getCodecPolicy());
388 assertEquals(CodecPolicy.LENIENT, Base32.builder().setDecodingPolicy(CodecPolicy.STRICT).setDecodingPolicy(null).get().getCodecPolicy());
389 assertEquals(CodecPolicy.LENIENT, Base32.builder().setDecodingPolicy(null).get().getCodecPolicy());
390 }
391
392 @Test
393 void testBuilderCustomEncodeTableAffectsDecodeTable() {
394 final byte[] encodeTable = ENCODE_TABLE.clone();
395 final byte temp = encodeTable[0];
396 encodeTable[0] = encodeTable[1];
397 encodeTable[1] = temp;
398 final Base32 base32 = Base32.builder().setEncodeTable(encodeTable).setLineLength(0).get();
399 final byte[] data = { 0 };
400 final byte[] encoded = base32.encode(data);
401 assertEquals("BB======", new String(encoded, StandardCharsets.US_ASCII));
402 assertArrayEquals(data, base32.decode(encoded));
403 }
404
405 @Test
406 void testBuilderCustomEncodeTableRejectsDuplicateEntries() {
407 final byte[] encodeTable = ENCODE_TABLE.clone();
408 encodeTable[1] = encodeTable[0];
409 assertThrows(IllegalArgumentException.class, () -> Base32.builder().setEncodeTable(encodeTable));
410 }
411
412 @Test
413 void testBuilderCustomEncodeTableRejectsInvalidLength() {
414 assertThrows(IllegalArgumentException.class, () -> Base32.builder().setEncodeTable(Arrays.copyOf(ENCODE_TABLE, ENCODE_TABLE.length - 1)));
415 }
416
417 @Test
418 void testBuilderCustomEncodeTableWithNonAsciiBytes() {
419 final byte[] encodeTable = new byte[32];
420 for (int i = 0; i < encodeTable.length; i++) {
421 encodeTable[i] = (byte) (0x80 + i);
422 }
423 final Base32 base32 = Base32.builder().setEncodeTable(encodeTable).setLineLength(0).get();
424 final byte[] data = { 0 };
425 final byte[] encoded = base32.encode(data);
426 assertArrayEquals(new byte[] { (byte) 0x80, (byte) 0x80, '=', '=', '=', '=', '=', '=' }, encoded);
427 assertTrue(base32.isInAlphabet((byte) 0x80));
428 assertArrayEquals(data, base32.decode(encoded));
429 }
430
431 @Test
432 void testBuilderLineAttributes() {
433 assertNull(Base32.builder().get().getLineSeparator());
434 assertNull(Base32.builder().setLineSeparator(BaseNCodec.CHUNK_SEPARATOR).get().getLineSeparator());
435 assertArrayEquals(BaseNCodec.CHUNK_SEPARATOR, Base32.builder().setLineLength(4).setLineSeparator(BaseNCodec.CHUNK_SEPARATOR).get().getLineSeparator());
436 assertArrayEquals(BaseNCodec.CHUNK_SEPARATOR, Base32.builder().setLineLength(4).setLineSeparator(null).get().getLineSeparator());
437 assertArrayEquals(BaseNCodec.CHUNK_SEPARATOR, Base32.builder().setLineLength(10).setLineSeparator(null).get().getLineSeparator());
438 assertNull(Base32.builder().setLineLength(-1).setLineSeparator(null).get().getLineSeparator());
439 assertNull(Base32.builder().setLineLength(0).setLineSeparator(null).get().getLineSeparator());
440 assertArrayEquals(new byte[] { 1 }, Base32.builder().setLineLength(4).setLineSeparator((byte) 1).get().getLineSeparator());
441 assertEquals("MZXXQ===", Base32.builder().setLineLength(4).get().encodeToString("fox".getBytes(CHARSET_UTF8)));
442 }
443
444 @Test
445 void testBuilderPadingByte() {
446 assertNull(Base32.builder().get().getLineSeparator());
447 assertNull(Base32.builder().setLineSeparator(BaseNCodec.CHUNK_SEPARATOR).get().getLineSeparator());
448 assertArrayEquals(BaseNCodec.CHUNK_SEPARATOR, Base32.builder().setLineLength(4).setLineSeparator(BaseNCodec.CHUNK_SEPARATOR).get().getLineSeparator());
449 assertArrayEquals(BaseNCodec.CHUNK_SEPARATOR, Base32.builder().setLineLength(4).setLineSeparator(null).get().getLineSeparator());
450 assertArrayEquals(BaseNCodec.CHUNK_SEPARATOR, Base32.builder().setLineLength(10).setLineSeparator(null).get().getLineSeparator());
451 assertNull(Base32.builder().setLineLength(-1).setLineSeparator(null).get().getLineSeparator());
452 assertNull(Base32.builder().setLineLength(0).setLineSeparator(null).get().getLineSeparator());
453 assertArrayEquals(new byte[] { 1 }, Base32.builder().setLineLength(4).setLineSeparator((byte) 1).get().getLineSeparator());
454 assertEquals("MZXXQ___", Base32.builder().setLineLength(4).setPadding((byte) '_').get().encodeToString("fox".getBytes(CHARSET_UTF8)));
455 }
456
457 @Test
458 void testBuilderSetHexDecodeTableDecodesOwnOutput() {
459 final Base32 base32 = Base32.builder().setHexDecodeTable(true).setLineLength(0).get();
460 final byte[] data = { 0 };
461 final byte[] encoded = base32.encode(data);
462 assertEquals("00======", new String(encoded, StandardCharsets.US_ASCII));
463 assertArrayEquals(data, base32.decode(encoded));
464 }
465
466 @Test
467 void testCodec200() {
468 final Base32 codec = new Base32(true, (byte) 'W');
469 assertNotNull(codec);
470 }
471
472 @Test
473 void testConstructors() {
474 Base32 base32;
475 base32 = new Base32();
476 base32 = new Base32(-1);
477 base32 = new Base32(-1, new byte[] {});
478 base32 = new Base32(32, new byte[] {});
479 base32 = new Base32(32, new byte[] {}, false);
480
481
482 base32 = new Base32(-1, new byte[] { 'A' });
483 base32 = new Base32(32, new byte[] { '$' });
484 assertArrayEquals(new byte[0], new Base32(32, null).getLineSeparator(), "null line separator use an empty array");
485 assertThrows(IllegalArgumentException.class, () -> new Base32(32, new byte[] { 'A' }), "'A' as a line separator");
486 assertThrows(IllegalArgumentException.class, () -> new Base32(32, new byte[] { '=' }), "'=' as a line separator");
487 assertThrows(IllegalArgumentException.class, () -> new Base32(32, new byte[] { 'A', '$' }), "'A$' as a line separator");
488 assertThrows(IllegalArgumentException.class, () -> new Base32(32, new byte[] { '\n' }, false, (byte) 'A'), "'A' as padding");
489 assertThrows(IllegalArgumentException.class, () -> new Base32(32, new byte[] { '\n' }, false, (byte) ' '), "' ' as padding");
490 base32 = new Base32(32, new byte[] { ' ', '$', '\n', '\r', '\t' });
491 assertNotNull(base32);
492 }
493
494
495
496
497 @Test
498 void testEmptyBase32() {
499 byte[] empty = {};
500 byte[] result = new Base32().encode(empty);
501 assertEquals(0, result.length, "empty Base32 encode");
502 assertNull(new Base32().encode(null), "empty Base32 encode");
503 result = new Base32().encode(empty, 0, 1);
504 assertEquals(0, result.length, "empty Base32 encode with offset");
505 assertNull(new Base32().encode(null), "empty Base32 encode with offset");
506
507 empty = new byte[0];
508 result = new Base32().decode(empty);
509 assertEquals(0, result.length, "empty Base32 decode");
510 assertNull(new Base32().decode((byte[]) null), "empty Base32 encode");
511 }
512
513 private void testImpossibleCases(final Base32 codec, final String[] impossible_cases) {
514 for (final String impossible : impossible_cases) {
515 assertThrows(IllegalArgumentException.class, () -> codec.decode(impossible));
516 }
517 }
518
519 @Test
520 void testIsInAlphabet() {
521
522 Base32 b32 = new Base32(true);
523 assertFalse(b32.isInAlphabet((byte) 0));
524 assertFalse(b32.isInAlphabet((byte) 1));
525 assertFalse(b32.isInAlphabet((byte) -1));
526 assertFalse(b32.isInAlphabet((byte) -15));
527 assertFalse(b32.isInAlphabet((byte) -32));
528 assertFalse(b32.isInAlphabet((byte) 127));
529 assertFalse(b32.isInAlphabet((byte) 128));
530 assertFalse(b32.isInAlphabet((byte) 255));
531
532
533 b32 = new Base32(false);
534 for (char c = '2'; c <= '7'; c++) {
535 assertTrue(b32.isInAlphabet((byte) c));
536 }
537 for (char c = 'A'; c <= 'Z'; c++) {
538 assertTrue(b32.isInAlphabet((byte) c));
539 }
540 for (char c = 'a'; c <= 'z'; c++) {
541 assertTrue(b32.isInAlphabet((byte) c));
542 }
543 assertFalse(b32.isInAlphabet((byte) '1'));
544 assertFalse(b32.isInAlphabet((byte) '8'));
545 assertFalse(b32.isInAlphabet((byte) ('A' - 1)));
546 assertFalse(b32.isInAlphabet((byte) ('Z' + 1)));
547
548
549 b32 = new Base32(true);
550 for (char c = '0'; c <= '9'; c++) {
551 assertTrue(b32.isInAlphabet((byte) c), String.valueOf(c));
552 }
553 for (char c = 'A'; c <= 'V'; c++) {
554 assertTrue(b32.isInAlphabet((byte) c));
555 }
556 for (char c = 'a'; c <= 'v'; c++) {
557 assertTrue(b32.isInAlphabet((byte) c));
558 }
559 assertFalse(b32.isInAlphabet((byte) ('0' - 1)));
560 assertFalse(b32.isInAlphabet((byte) ('9' + 1)));
561 assertFalse(b32.isInAlphabet((byte) ('A' - 1)));
562 assertFalse(b32.isInAlphabet((byte) ('V' + 1)));
563 assertFalse(b32.isInAlphabet((byte) ('a' - 1)));
564 assertFalse(b32.isInAlphabet((byte) ('v' + 1)));
565 }
566
567 @ParameterizedTest
568 @MethodSource("rangeProvider")
569 void testRandomBytes(final int i) {
570 final Base32 codec = new Base32();
571 final byte[][] b = BaseNTestData.randomData(codec, i);
572 assertEquals(b[1].length, codec.getEncodedLength(b[0]), i + " " + codec.lineLength);
573
574 }
575
576 @ParameterizedTest
577 @MethodSource("rangeProvider")
578 void testRandomBytesChunked(final int i) {
579 final Base32 codec = new Base32(10);
580 final byte[][] b = BaseNTestData.randomData(codec, i);
581 assertEquals(b[1].length, codec.getEncodedLength(b[0]), i + " " + codec.lineLength);
582
583 }
584
585 @ParameterizedTest
586 @MethodSource("rangeProvider")
587 void testRandomBytesHex(final int i) {
588 final Base32 codec = new Base32(true);
589 final byte[][] b = BaseNTestData.randomData(codec, i);
590 assertEquals(b[1].length, codec.getEncodedLength(b[0]), i + " " + codec.lineLength);
591
592 }
593
594 @ParameterizedTest
595 @MethodSource("rangeProvider")
596 void testSingleCharEncoding(final int i) {
597 Base32 codec = new Base32();
598 final BaseNCodec.Context context = new BaseNCodec.Context();
599 final byte[] unencoded = new byte[i];
600 final byte[] allInOne = codec.encode(unencoded);
601 codec = new Base32();
602 for (int j = 0; j < unencoded.length; j++) {
603 codec.encode(unencoded, j, 1, context);
604 }
605 codec.encode(unencoded, 0, -1, context);
606 final byte[] singly = new byte[allInOne.length];
607 codec.readResults(singly, 0, 100, context);
608 assertArrayEquals(allInOne, singly);
609 }
610 }