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.assertNull;
24 import static org.junit.jupiter.api.Assertions.assertThrows;
25 import static org.junit.jupiter.api.Assertions.assertTrue;
26
27 import java.nio.charset.Charset;
28 import java.nio.charset.StandardCharsets;
29 import java.util.Random;
30
31 import org.apache.commons.codec.CodecPolicy;
32 import org.apache.commons.codec.DecoderException;
33 import org.apache.commons.codec.EncoderException;
34 import org.apache.commons.lang3.ArrayUtils;
35 import org.junit.jupiter.api.Test;
36
37
38
39
40 class Base16Test {
41
42 private static final Charset CHARSET_UTF8 = StandardCharsets.UTF_8;
43
44 private final Random random = new Random();
45
46
47
48
49
50
51 Random getRandom() {
52 return this.random;
53 }
54
55
56
57
58 @Test
59 void testBase16() {
60 final String content = "Hello World";
61 final byte[] encodedBytes = new Base16().encode(StringUtils.getBytesUtf8(content));
62 final String encodedContent = StringUtils.newStringUtf8(encodedBytes);
63 assertEquals("48656C6C6F20576F726C64", encodedContent, "encoding hello world");
64
65 final byte[] decodedBytes = new Base16().decode(encodedBytes);
66 final String decodedContent = StringUtils.newStringUtf8(decodedBytes);
67 assertEquals(content, decodedContent, "decoding hello world");
68 }
69
70 @Test
71 void testBase16AtBufferEnd() {
72 testBase16InBuffer(100, 0);
73 }
74
75 @Test
76 void testBase16AtBufferMiddle() {
77 testBase16InBuffer(100, 100);
78 }
79
80 @Test
81 void testBase16AtBufferStart() {
82 testBase16InBuffer(0, 100);
83 }
84
85 private void testBase16InBuffer(final int startPasSize, final int endPadSize) {
86 final String content = "Hello World";
87 final String encodedContent;
88 final byte[] bytesUtf8 = StringUtils.getBytesUtf8(content);
89 byte[] buffer = ArrayUtils.addAll(bytesUtf8, new byte[endPadSize]);
90 buffer = ArrayUtils.addAll(new byte[startPasSize], buffer);
91 final byte[] encodedBytes = new Base16().encode(buffer, startPasSize, bytesUtf8.length);
92 encodedContent = StringUtils.newStringUtf8(encodedBytes);
93 assertEquals("48656C6C6F20576F726C64", encodedContent, "encoding hello world");
94 }
95
96 @Test
97 void testBuilderSetLowerCaseDecodesOwnOutput() {
98 final Base16 base16 = Base16.builder().setLowerCase(true).get();
99 final byte[] data = { (byte) 0xab };
100 final byte[] encoded = base16.encode(data);
101 assertEquals("ab", new String(encoded, StandardCharsets.US_ASCII));
102 assertArrayEquals(data, base16.decode(encoded));
103 }
104
105 @Test
106 void testByteToStringVariations() {
107 final Base16 base16 = new Base16();
108 final byte[] b1 = StringUtils.getBytesUtf8("Hello World");
109 final byte[] b2 = {};
110 final byte[] b3 = null;
111
112 assertEquals("48656C6C6F20576F726C64", base16.encodeToString(b1), "byteToString Hello World");
113 assertEquals("48656C6C6F20576F726C64", StringUtils.newStringUtf8(new Base16().encode(b1)), "byteToString static Hello World");
114 assertEquals("", base16.encodeToString(b2), "byteToString \"\"");
115 assertEquals("", StringUtils.newStringUtf8(new Base16().encode(b2)), "byteToString static \"\"");
116 assertNull(base16.encodeToString(b3), "byteToString null");
117 assertNull(StringUtils.newStringUtf8(new Base16().encode(b3)), "byteToString static null");
118 }
119
120 @Test
121 void testCheckEncodeLengthBounds() {
122 final Base16 base16 = new Base16();
123 assertThrows(IllegalArgumentException.class, () -> base16.encode(new byte[10], 0, 1 << 30));
124 }
125
126
127
128
129 @Test
130 void testCodec68() {
131 final byte[] x = { 'n', 'H', '=', '=', (byte) 0x9c };
132 final Base16 b16 = new Base16();
133 assertThrows(RuntimeException.class, () -> b16.decode(x));
134 }
135
136 @Test
137 void testConstructor_LowerCase() {
138 final Base16 base16 = new Base16(true);
139 final byte[] encoded = base16.encode(BaseNTestData.DECODED);
140 final String expectedResult = Base16TestData.ENCODED_UTF8_LOWERCASE;
141 final String result = StringUtils.newStringUtf8(encoded);
142 assertEquals(expectedResult, result, "new Base16(true)");
143 }
144
145 @Test
146 void testConstructor_LowerCase_DecodingPolicy() {
147 final Base16 base16 = new Base16(false, CodecPolicy.STRICT);
148 final byte[] encoded = base16.encode(BaseNTestData.DECODED);
149 final String expectedResult = Base16TestData.ENCODED_UTF8_UPPERCASE;
150 final String result = StringUtils.newStringUtf8(encoded);
151 assertEquals(result, expectedResult, "new base16(false, CodecPolicy.STRICT)");
152 }
153
154 @Test
155 void testConstructors() {
156 new Base16();
157 new Base16(false);
158 new Base16(true);
159 new Base16(false, CodecPolicy.LENIENT);
160 new Base16(false, CodecPolicy.STRICT);
161 }
162
163 @Test
164 void testCustomEncodeTableAffectsDecodeTable() {
165 final byte[] encodeTable = "0123456789ABCDEF".getBytes(StandardCharsets.US_ASCII);
166 final byte tmp = encodeTable[0];
167 encodeTable[0] = encodeTable[1];
168 encodeTable[1] = tmp;
169 final Base16 base16 = Base16.builder().setEncodeTable(encodeTable).get();
170 final byte[] encoded = base16.encode(new byte[] { 1 });
171 assertEquals("10", new String(encoded, StandardCharsets.US_ASCII));
172 assertArrayEquals(new byte[] { 1 }, base16.decode(encoded));
173 }
174
175 @Test
176 void testCustomEncodeTableRejectsDuplicates() {
177 final byte[] encodeTable = "00123456789ABCDE".getBytes(StandardCharsets.US_ASCII);
178 assertThrows(IllegalArgumentException.class, () -> Base16.builder().setEncodeTable(encodeTable));
179 }
180
181 @Test
182 void testCustomEncodeTableRejectsInvalidLength() {
183 assertThrows(IllegalArgumentException.class,
184 () -> Base16.builder().setEncodeTable("0123456789ABCDE".getBytes(StandardCharsets.US_ASCII)));
185 }
186
187 @Test
188 void testDecodeSingleBytes() {
189 final String encoded = "556E74696C206E6578742074696D6521";
190
191 final BaseNCodec.Context context = new BaseNCodec.Context();
192 final Base16 b16 = new Base16();
193
194 final byte[] encocdedBytes = StringUtils.getBytesUtf8(encoded);
195
196
197 b16.decode(encocdedBytes, 0, 1, context);
198 b16.decode(encocdedBytes, 1, 1, context);
199 b16.decode(encocdedBytes, 2, 1, context);
200 b16.decode(encocdedBytes, 3, 1, context);
201
202
203 b16.decode(encocdedBytes, 4, 3, context);
204 b16.decode(encocdedBytes, 7, 3, context);
205 b16.decode(encocdedBytes, 10, 3, context);
206
207
208 b16.decode(encocdedBytes, 13, 19, context);
209
210 final byte[] decodedBytes = new byte[context.pos];
211 System.arraycopy(context.buffer, context.readPos, decodedBytes, 0, decodedBytes.length);
212 final String decoded = StringUtils.newStringUtf8(decodedBytes);
213
214 assertEquals("Until next time!", decoded);
215 }
216
217 @Test
218 void testDecodeSingleBytesOptimization() {
219 final BaseNCodec.Context context = new BaseNCodec.Context();
220 assertEquals(0, context.ibitWorkArea);
221 assertNull(context.buffer);
222
223 final byte[] data = new byte[1];
224
225 final Base16 b16 = new Base16();
226
227 data[0] = (byte) 'E';
228 b16.decode(data, 0, 1, context);
229 assertEquals(15, context.ibitWorkArea);
230 assertNull(context.buffer);
231
232 data[0] = (byte) 'F';
233 b16.decode(data, 0, 1, context);
234 assertEquals(0, context.ibitWorkArea);
235
236 assertEquals((byte) 0xEF, context.buffer[0]);
237 }
238
239
240
241
242 @Test
243 void testEmptyBase16() {
244 byte[] empty = {};
245 byte[] result = new Base16().encode(empty);
246 assertEquals(0, result.length, "empty Base16 encode");
247 assertNull(new Base16().encode(null), "empty Base16 encode");
248 result = new Base16().encode(empty, 0, 1);
249 assertEquals(0, result.length, "empty Base16 encode with offset");
250 assertNull(new Base16().encode(null), "empty Base16 encode with offset");
251
252 empty = new byte[0];
253 result = new Base16().decode(empty);
254 assertEquals(0, result.length, "empty Base16 decode");
255 assertNull(new Base16().decode((byte[]) null), "empty Base16 encode");
256 }
257
258
259 @Test
260 void testEncodeDecodeRandom() {
261 for (int i = 1; i < 5; i++) {
262 final int len = getRandom().nextInt(10000) + 1;
263 final byte[] data = new byte[len];
264 getRandom().nextBytes(data);
265 final byte[] enc = new Base16().encode(data);
266 final byte[] data2 = new Base16().decode(enc);
267 assertArrayEquals(data, data2);
268 }
269 }
270
271
272 @Test
273 void testEncodeDecodeSmall() {
274 for (int i = 0; i < 12; i++) {
275 final byte[] data = new byte[i];
276 getRandom().nextBytes(data);
277 final byte[] enc = new Base16().encode(data);
278 final byte[] data2 = new Base16().decode(enc);
279 assertArrayEquals(data, data2, toString(data) + " equals " + toString(data2));
280 }
281 }
282
283 @Test
284 void testIsInAlphabet() {
285
286 Base16 b16 = Base16.builder().setLowerCase(true).get();
287 assertFalse(b16.isInAlphabet((byte) 0));
288 assertFalse(b16.isInAlphabet((byte) 1));
289 assertFalse(b16.isInAlphabet((byte) -1));
290 assertFalse(b16.isInAlphabet((byte) -15));
291 assertFalse(b16.isInAlphabet((byte) -16));
292 assertFalse(b16.isInAlphabet((byte) 128));
293 assertFalse(b16.isInAlphabet((byte) 255));
294
295 b16 = new Base16(true);
296 for (char c = '0'; c <= '9'; c++) {
297 assertTrue(b16.isInAlphabet((byte) c));
298 }
299 for (char c = 'a'; c <= 'f'; c++) {
300 assertTrue(b16.isInAlphabet((byte) c));
301 }
302 for (char c = 'A'; c <= 'F'; c++) {
303 assertFalse(b16.isInAlphabet((byte) c));
304 }
305 assertFalse(b16.isInAlphabet((byte) ('0' - 1)));
306 assertFalse(b16.isInAlphabet((byte) ('9' + 1)));
307 assertFalse(b16.isInAlphabet((byte) ('a' - 1)));
308 assertFalse(b16.isInAlphabet((byte) ('f' + 1)));
309 assertFalse(b16.isInAlphabet((byte) ('z' + 1)));
310
311 b16 = new Base16(false);
312 for (char c = '0'; c <= '9'; c++) {
313 assertTrue(b16.isInAlphabet((byte) c));
314 }
315 for (char c = 'a'; c <= 'f'; c++) {
316 assertFalse(b16.isInAlphabet((byte) c));
317 }
318 for (char c = 'A'; c <= 'F'; c++) {
319 assertTrue(b16.isInAlphabet((byte) c));
320 }
321 assertFalse(b16.isInAlphabet((byte) ('0' - 1)));
322 assertFalse(b16.isInAlphabet((byte) ('9' + 1)));
323 assertFalse(b16.isInAlphabet((byte) ('A' - 1)));
324 assertFalse(b16.isInAlphabet((byte) ('F' + 1)));
325 assertFalse(b16.isInAlphabet((byte) ('Z' + 1)));
326 }
327
328 @Test
329 void testKnownDecodings() {
330 assertEquals("The quick brown fox jumped over the lazy dogs.", new String(new Base16(true)
331 .decode("54686520717569636b2062726f776e20666f78206a756d706564206f76657220746865206c617a7920646f67732e".getBytes(CHARSET_UTF8))));
332 assertEquals("It was the best of times, it was the worst of times.", new String(new Base16(true)
333 .decode("497420776173207468652062657374206f662074696d65732c206974207761732074686520776f727374206f662074696d65732e".getBytes(CHARSET_UTF8))));
334 assertEquals("http://jakarta.apache.org/commmons",
335 new String(new Base16(true).decode("687474703a2f2f6a616b617274612e6170616368652e6f72672f636f6d6d6d6f6e73".getBytes(CHARSET_UTF8))));
336 assertEquals("AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz", new String(new Base16(true)
337 .decode("4161426243634464456546664767486849694a6a4b6b4c6c4d6d4e6e4f6f50705171527253735474557556765777587859795a7a".getBytes(CHARSET_UTF8))));
338 assertEquals("{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }",
339 new String(new Base16(true).decode("7b20302c20312c20322c20332c20342c20352c20362c20372c20382c2039207d".getBytes(CHARSET_UTF8))));
340 assertEquals("xyzzy!", new String(new Base16(true).decode("78797a7a7921".getBytes(CHARSET_UTF8))));
341 }
342
343 @Test
344 void testKnownEncodings() {
345 assertEquals("54686520717569636b2062726f776e20666f78206a756d706564206f76657220746865206c617a7920646f67732e",
346 new String(new Base16(true).encode("The quick brown fox jumped over the lazy dogs.".getBytes(CHARSET_UTF8))));
347 assertEquals("497420776173207468652062657374206f662074696d65732c206974207761732074686520776f727374206f662074696d65732e",
348 new String(new Base16(true).encode("It was the best of times, it was the worst of times.".getBytes(CHARSET_UTF8))));
349 assertEquals("687474703a2f2f6a616b617274612e6170616368652e6f72672f636f6d6d6d6f6e73",
350 new String(new Base16(true).encode("http://jakarta.apache.org/commmons".getBytes(CHARSET_UTF8))));
351 assertEquals("4161426243634464456546664767486849694a6a4b6b4c6c4d6d4e6e4f6f50705171527253735474557556765777587859795a7a",
352 new String(new Base16(true).encode("AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz".getBytes(CHARSET_UTF8))));
353 assertEquals("7b20302c20312c20322c20332c20342c20352c20362c20372c20382c2039207d",
354 new String(new Base16(true).encode("{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }".getBytes(CHARSET_UTF8))));
355 assertEquals("78797a7a7921", new String(new Base16(true).encode("xyzzy!".getBytes(CHARSET_UTF8))));
356 }
357
358 @Test
359 void testLenientDecoding() {
360 final String encoded = "aabbccdde";
361
362 final Base16 b16 = new Base16(true, CodecPolicy.LENIENT);
363 assertEquals(CodecPolicy.LENIENT, b16.getCodecPolicy());
364
365 final byte[] decoded = b16.decode(StringUtils.getBytesUtf8(encoded));
366 assertArrayEquals(new byte[] { (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd }, decoded);
367 }
368
369 @Test
370 void testNonBase16Test() {
371 final byte[] invalidEncodedChars = { '/', ':', '@', 'G', '%', '`', 'g' };
372
373 final byte[] encoded = new byte[1];
374 for (final byte invalidEncodedChar : invalidEncodedChars) {
375 encoded[0] = invalidEncodedChar;
376 assertThrows(IllegalArgumentException.class, () -> new Base16().decode(encoded), "Invalid Base16 char: " + (char) invalidEncodedChar);
377 }
378 }
379
380 @Test
381 void testObjectDecodeWithInvalidParameter() {
382 assertThrows(DecoderException.class, () -> new Base16().decode(Integer.valueOf(5)));
383 }
384
385 @Test
386 void testObjectDecodeWithValidParameter() throws Exception {
387 final String original = "Hello World!";
388 final Object o = new Base16().encode(original.getBytes(CHARSET_UTF8));
389
390 final Base16 b16 = new Base16();
391 final Object oDecoded = b16.decode(o);
392 final byte[] baDecoded = (byte[]) oDecoded;
393 final String dest = new String(baDecoded);
394
395 assertEquals(original, dest, "dest string does not equal original");
396 }
397
398 @Test
399 void testObjectEncode() {
400 final Base16 b16 = new Base16();
401 assertEquals(new String(b16.encode("Hello World".getBytes(CHARSET_UTF8))), "48656C6C6F20576F726C64");
402 }
403
404 @Test
405 void testObjectEncodeWithInvalidParameter() {
406 assertThrows(EncoderException.class, () -> new Base16().encode("Yadayadayada"));
407 }
408
409 @Test
410 void testObjectEncodeWithValidParameter() throws Exception {
411 final String original = "Hello World!";
412 final Object origObj = original.getBytes(CHARSET_UTF8);
413
414 final Object oEncoded = new Base16().encode(origObj);
415 final byte[] bArray = new Base16().decode((byte[]) oEncoded);
416 final String dest = new String(bArray);
417
418 assertEquals(original, dest, "dest string does not equal original");
419 }
420
421 @Test
422 void testOddEvenDecoding() {
423 final String encoded = "4142434445";
424
425 final BaseNCodec.Context context = new BaseNCodec.Context();
426 final Base16 base16 = new Base16();
427
428 final byte[] encodedBytes = StringUtils.getBytesUtf8(encoded);
429
430
431 base16.decode(encodedBytes, 0, 3, context);
432 base16.decode(encodedBytes, 3, 4, context);
433 base16.decode(encodedBytes, 7, 3, context);
434
435 final byte[] decodedBytes = new byte[context.pos];
436 System.arraycopy(context.buffer, context.readPos, decodedBytes, 0, decodedBytes.length);
437 final String decoded = StringUtils.newStringUtf8(decodedBytes);
438
439 assertEquals("ABCDE", decoded);
440 }
441
442 @Test
443 void testPairs() {
444 assertEquals("0000", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 0 })));
445 assertEquals("0001", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 1 })));
446 assertEquals("0002", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 2 })));
447 assertEquals("0003", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 3 })));
448 assertEquals("0004", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 4 })));
449 assertEquals("0005", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 5 })));
450 assertEquals("0006", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 6 })));
451 assertEquals("0007", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 7 })));
452 assertEquals("0008", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 8 })));
453 assertEquals("0009", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 9 })));
454 assertEquals("000A", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 10 })));
455 assertEquals("000B", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 11 })));
456 assertEquals("000C", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 12 })));
457 assertEquals("000D", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 13 })));
458 assertEquals("000E", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 14 })));
459 assertEquals("000F", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 15 })));
460 assertEquals("0010", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 16 })));
461 assertEquals("0011", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 17 })));
462 for (int i = -128; i <= 127; i++) {
463 final byte[] test = { (byte) i, (byte) i };
464 assertArrayEquals(test, new Base16().decode(new Base16().encode(test)));
465 }
466 }
467
468 @Test
469 void testSingletons() {
470 assertEquals("00", new String(new Base16().encode(new byte[] { (byte) 0 })));
471 assertEquals("01", new String(new Base16().encode(new byte[] { (byte) 1 })));
472 assertEquals("02", new String(new Base16().encode(new byte[] { (byte) 2 })));
473 assertEquals("03", new String(new Base16().encode(new byte[] { (byte) 3 })));
474 assertEquals("04", new String(new Base16().encode(new byte[] { (byte) 4 })));
475 assertEquals("05", new String(new Base16().encode(new byte[] { (byte) 5 })));
476 assertEquals("06", new String(new Base16().encode(new byte[] { (byte) 6 })));
477 assertEquals("07", new String(new Base16().encode(new byte[] { (byte) 7 })));
478 assertEquals("08", new String(new Base16().encode(new byte[] { (byte) 8 })));
479 assertEquals("09", new String(new Base16().encode(new byte[] { (byte) 9 })));
480 assertEquals("0A", new String(new Base16().encode(new byte[] { (byte) 10 })));
481 assertEquals("0B", new String(new Base16().encode(new byte[] { (byte) 11 })));
482 assertEquals("0C", new String(new Base16().encode(new byte[] { (byte) 12 })));
483 assertEquals("0D", new String(new Base16().encode(new byte[] { (byte) 13 })));
484 assertEquals("0E", new String(new Base16().encode(new byte[] { (byte) 14 })));
485 assertEquals("0F", new String(new Base16().encode(new byte[] { (byte) 15 })));
486 assertEquals("10", new String(new Base16().encode(new byte[] { (byte) 16 })));
487 assertEquals("11", new String(new Base16().encode(new byte[] { (byte) 17 })));
488 assertEquals("12", new String(new Base16().encode(new byte[] { (byte) 18 })));
489 assertEquals("13", new String(new Base16().encode(new byte[] { (byte) 19 })));
490 assertEquals("14", new String(new Base16().encode(new byte[] { (byte) 20 })));
491 assertEquals("15", new String(new Base16().encode(new byte[] { (byte) 21 })));
492 assertEquals("16", new String(new Base16().encode(new byte[] { (byte) 22 })));
493 assertEquals("17", new String(new Base16().encode(new byte[] { (byte) 23 })));
494 assertEquals("18", new String(new Base16().encode(new byte[] { (byte) 24 })));
495 assertEquals("19", new String(new Base16().encode(new byte[] { (byte) 25 })));
496 assertEquals("1A", new String(new Base16().encode(new byte[] { (byte) 26 })));
497 assertEquals("1B", new String(new Base16().encode(new byte[] { (byte) 27 })));
498 assertEquals("1C", new String(new Base16().encode(new byte[] { (byte) 28 })));
499 assertEquals("1D", new String(new Base16().encode(new byte[] { (byte) 29 })));
500 assertEquals("1E", new String(new Base16().encode(new byte[] { (byte) 30 })));
501 assertEquals("1F", new String(new Base16().encode(new byte[] { (byte) 31 })));
502 assertEquals("20", new String(new Base16().encode(new byte[] { (byte) 32 })));
503 assertEquals("21", new String(new Base16().encode(new byte[] { (byte) 33 })));
504 assertEquals("22", new String(new Base16().encode(new byte[] { (byte) 34 })));
505 assertEquals("23", new String(new Base16().encode(new byte[] { (byte) 35 })));
506 assertEquals("24", new String(new Base16().encode(new byte[] { (byte) 36 })));
507 assertEquals("25", new String(new Base16().encode(new byte[] { (byte) 37 })));
508 assertEquals("26", new String(new Base16().encode(new byte[] { (byte) 38 })));
509 assertEquals("27", new String(new Base16().encode(new byte[] { (byte) 39 })));
510 assertEquals("28", new String(new Base16().encode(new byte[] { (byte) 40 })));
511 assertEquals("29", new String(new Base16().encode(new byte[] { (byte) 41 })));
512 assertEquals("2A", new String(new Base16().encode(new byte[] { (byte) 42 })));
513 assertEquals("2B", new String(new Base16().encode(new byte[] { (byte) 43 })));
514 assertEquals("2C", new String(new Base16().encode(new byte[] { (byte) 44 })));
515 assertEquals("2D", new String(new Base16().encode(new byte[] { (byte) 45 })));
516 assertEquals("2E", new String(new Base16().encode(new byte[] { (byte) 46 })));
517 assertEquals("2F", new String(new Base16().encode(new byte[] { (byte) 47 })));
518 assertEquals("30", new String(new Base16().encode(new byte[] { (byte) 48 })));
519 assertEquals("31", new String(new Base16().encode(new byte[] { (byte) 49 })));
520 assertEquals("32", new String(new Base16().encode(new byte[] { (byte) 50 })));
521 assertEquals("33", new String(new Base16().encode(new byte[] { (byte) 51 })));
522 assertEquals("34", new String(new Base16().encode(new byte[] { (byte) 52 })));
523 assertEquals("35", new String(new Base16().encode(new byte[] { (byte) 53 })));
524 assertEquals("36", new String(new Base16().encode(new byte[] { (byte) 54 })));
525 assertEquals("37", new String(new Base16().encode(new byte[] { (byte) 55 })));
526 assertEquals("38", new String(new Base16().encode(new byte[] { (byte) 56 })));
527 assertEquals("39", new String(new Base16().encode(new byte[] { (byte) 57 })));
528 assertEquals("3A", new String(new Base16().encode(new byte[] { (byte) 58 })));
529 assertEquals("3B", new String(new Base16().encode(new byte[] { (byte) 59 })));
530 assertEquals("3C", new String(new Base16().encode(new byte[] { (byte) 60 })));
531 assertEquals("3D", new String(new Base16().encode(new byte[] { (byte) 61 })));
532 assertEquals("3E", new String(new Base16().encode(new byte[] { (byte) 62 })));
533 assertEquals("3F", new String(new Base16().encode(new byte[] { (byte) 63 })));
534 assertEquals("40", new String(new Base16().encode(new byte[] { (byte) 64 })));
535 assertEquals("41", new String(new Base16().encode(new byte[] { (byte) 65 })));
536 assertEquals("42", new String(new Base16().encode(new byte[] { (byte) 66 })));
537 assertEquals("43", new String(new Base16().encode(new byte[] { (byte) 67 })));
538 assertEquals("44", new String(new Base16().encode(new byte[] { (byte) 68 })));
539 assertEquals("45", new String(new Base16().encode(new byte[] { (byte) 69 })));
540 assertEquals("46", new String(new Base16().encode(new byte[] { (byte) 70 })));
541 assertEquals("47", new String(new Base16().encode(new byte[] { (byte) 71 })));
542 assertEquals("48", new String(new Base16().encode(new byte[] { (byte) 72 })));
543 assertEquals("49", new String(new Base16().encode(new byte[] { (byte) 73 })));
544 assertEquals("4A", new String(new Base16().encode(new byte[] { (byte) 74 })));
545 assertEquals("4B", new String(new Base16().encode(new byte[] { (byte) 75 })));
546 assertEquals("4C", new String(new Base16().encode(new byte[] { (byte) 76 })));
547 assertEquals("4D", new String(new Base16().encode(new byte[] { (byte) 77 })));
548 assertEquals("4E", new String(new Base16().encode(new byte[] { (byte) 78 })));
549 assertEquals("4F", new String(new Base16().encode(new byte[] { (byte) 79 })));
550 assertEquals("50", new String(new Base16().encode(new byte[] { (byte) 80 })));
551 assertEquals("51", new String(new Base16().encode(new byte[] { (byte) 81 })));
552 assertEquals("52", new String(new Base16().encode(new byte[] { (byte) 82 })));
553 assertEquals("53", new String(new Base16().encode(new byte[] { (byte) 83 })));
554 assertEquals("54", new String(new Base16().encode(new byte[] { (byte) 84 })));
555 assertEquals("55", new String(new Base16().encode(new byte[] { (byte) 85 })));
556 assertEquals("56", new String(new Base16().encode(new byte[] { (byte) 86 })));
557 assertEquals("57", new String(new Base16().encode(new byte[] { (byte) 87 })));
558 assertEquals("58", new String(new Base16().encode(new byte[] { (byte) 88 })));
559 assertEquals("59", new String(new Base16().encode(new byte[] { (byte) 89 })));
560 assertEquals("5A", new String(new Base16().encode(new byte[] { (byte) 90 })));
561 assertEquals("5B", new String(new Base16().encode(new byte[] { (byte) 91 })));
562 assertEquals("5C", new String(new Base16().encode(new byte[] { (byte) 92 })));
563 assertEquals("5D", new String(new Base16().encode(new byte[] { (byte) 93 })));
564 assertEquals("5E", new String(new Base16().encode(new byte[] { (byte) 94 })));
565 assertEquals("5F", new String(new Base16().encode(new byte[] { (byte) 95 })));
566 assertEquals("60", new String(new Base16().encode(new byte[] { (byte) 96 })));
567 assertEquals("61", new String(new Base16().encode(new byte[] { (byte) 97 })));
568 assertEquals("62", new String(new Base16().encode(new byte[] { (byte) 98 })));
569 assertEquals("63", new String(new Base16().encode(new byte[] { (byte) 99 })));
570 assertEquals("64", new String(new Base16().encode(new byte[] { (byte) 100 })));
571 assertEquals("65", new String(new Base16().encode(new byte[] { (byte) 101 })));
572 assertEquals("66", new String(new Base16().encode(new byte[] { (byte) 102 })));
573 assertEquals("67", new String(new Base16().encode(new byte[] { (byte) 103 })));
574 assertEquals("68", new String(new Base16().encode(new byte[] { (byte) 104 })));
575 for (int i = -128; i <= 127; i++) {
576 final byte[] test = { (byte) i };
577 assertArrayEquals(test, new Base16().decode(new Base16().encode(test)));
578 }
579 }
580
581 @Test
582 void testStrictDecoding() {
583 final String encoded = "aabbccdde";
584
585 final Base16 b16 = new Base16(true, CodecPolicy.STRICT);
586 assertEquals(CodecPolicy.STRICT, b16.getCodecPolicy());
587 assertThrows(IllegalArgumentException.class, () -> b16.decode(StringUtils.getBytesUtf8(encoded)));
588 }
589
590 @Test
591 void testStringToByteVariations() throws DecoderException {
592 final Base16 base16 = new Base16();
593 final String s1 = "48656C6C6F20576F726C64";
594 final String s2 = "";
595 final String s3 = null;
596
597 assertEquals("Hello World", StringUtils.newStringUtf8(base16.decode(s1)), "StringToByte Hello World");
598 assertEquals("Hello World", StringUtils.newStringUtf8((byte[]) new Base16().decode((Object) s1)), "StringToByte Hello World");
599 assertEquals("Hello World", StringUtils.newStringUtf8(new Base16().decode(s1)), "StringToByte static Hello World");
600 assertEquals("", StringUtils.newStringUtf8(new Base16().decode(s2)), "StringToByte \"\"");
601 assertEquals("", StringUtils.newStringUtf8(new Base16().decode(s2)), "StringToByte static \"\"");
602 assertNull(StringUtils.newStringUtf8(new Base16().decode(s3)), "StringToByte null");
603 assertNull(StringUtils.newStringUtf8(new Base16().decode(s3)), "StringToByte static null");
604 }
605
606 @Test
607 void testTriplets() {
608 assertEquals("000000", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 0, (byte) 0 })));
609 assertEquals("000001", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 0, (byte) 1 })));
610 assertEquals("000002", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 0, (byte) 2 })));
611 assertEquals("000003", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 0, (byte) 3 })));
612 assertEquals("000004", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 0, (byte) 4 })));
613 assertEquals("000005", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 0, (byte) 5 })));
614 assertEquals("000006", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 0, (byte) 6 })));
615 assertEquals("000007", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 0, (byte) 7 })));
616 assertEquals("000008", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 0, (byte) 8 })));
617 assertEquals("000009", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 0, (byte) 9 })));
618 assertEquals("00000A", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 0, (byte) 10 })));
619 assertEquals("00000B", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 0, (byte) 11 })));
620 assertEquals("00000C", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 0, (byte) 12 })));
621 assertEquals("00000D", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 0, (byte) 13 })));
622 assertEquals("00000E", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 0, (byte) 14 })));
623 assertEquals("00000F", new String(new Base16().encode(new byte[] { (byte) 0, (byte) 0, (byte) 15 })));
624 }
625
626 private String toString(final byte[] data) {
627 final StringBuilder buf = new StringBuilder();
628 for (int i = 0; i < data.length; i++) {
629 buf.append(data[i]);
630 if (i != data.length - 1) {
631 buf.append(",");
632 }
633 }
634 return buf.toString();
635 }
636 }