@@ -159,6 +159,17 @@ public Base32() {
159159 this (false );
160160 }
161161
162+ /**
163+ * Creates a Base32 codec used for decoding and encoding.
164+ * <p>
165+ * When encoding the line length is 0 (no chunking).
166+ * </p>
167+ * @param pad byte used as padding byte.
168+ */
169+ public Base32 (final byte pad ) {
170+ this (false , pad );
171+ }
172+
162173 /**
163174 * Creates a Base32 codec used for decoding and encoding.
164175 * <p>
@@ -167,7 +178,19 @@ public Base32() {
167178 * @param useHex if {@code true} then use Base32 Hex alphabet
168179 */
169180 public Base32 (final boolean useHex ) {
170- this (0 , null , useHex );
181+ this (0 , null , useHex , PAD_DEFAULT );
182+ }
183+
184+ /**
185+ * Creates a Base32 codec used for decoding and encoding.
186+ * <p>
187+ * When encoding the line length is 0 (no chunking).
188+ * </p>
189+ * @param useHex if {@code true} then use Base32 Hex alphabet
190+ * @param pad byte used as padding byte.
191+ */
192+ public Base32 (final boolean useHex , final byte pad ) {
193+ this (0 , null , useHex , pad );
171194 }
172195
173196 /**
@@ -204,7 +227,7 @@ public Base32(final int lineLength) {
204227 * The provided lineSeparator included some Base32 characters. That's not going to work!
205228 */
206229 public Base32 (final int lineLength , final byte [] lineSeparator ) {
207- this (lineLength , lineSeparator , false );
230+ this (lineLength , lineSeparator , false , PAD_DEFAULT );
208231 }
209232
210233 /**
@@ -229,10 +252,35 @@ public Base32(final int lineLength, final byte[] lineSeparator) {
229252 * lineLength > 0 and lineSeparator is null.
230253 */
231254 public Base32 (final int lineLength , final byte [] lineSeparator , final boolean useHex ) {
232- super (BYTES_PER_UNENCODED_BLOCK , BYTES_PER_ENCODED_BLOCK ,
233- lineLength ,
234- lineSeparator == null ? 0 : lineSeparator .length );
235- if (useHex ){
255+ this (lineLength , lineSeparator , useHex , PAD_DEFAULT );
256+ }
257+
258+ /**
259+ * Creates a Base32 / Base32 Hex codec used for decoding and encoding.
260+ * <p>
261+ * When encoding the line length and line separator are given in the constructor.
262+ * </p>
263+ * <p>
264+ * Line lengths that aren't multiples of 8 will still essentially end up being multiples of 8 in the encoded data.
265+ * </p>
266+ *
267+ * @param lineLength
268+ * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of
269+ * 8). If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when
270+ * decoding.
271+ * @param lineSeparator
272+ * Each line of encoded data will end with this sequence of bytes.
273+ * @param useHex
274+ * if {@code true}, then use Base32 Hex alphabet, otherwise use Base32 alphabet
275+ * @param pad byte used as padding byte.
276+ * @throws IllegalArgumentException
277+ * The provided lineSeparator included some Base32 characters. That's not going to work! Or the
278+ * lineLength > 0 and lineSeparator is null.
279+ */
280+ public Base32 (final int lineLength , final byte [] lineSeparator , final boolean useHex , final byte pad ) {
281+ super (BYTES_PER_UNENCODED_BLOCK , BYTES_PER_ENCODED_BLOCK , lineLength ,
282+ lineSeparator == null ? 0 : lineSeparator .length , pad );
283+ if (useHex ) {
236284 this .encodeTable = HEX_ENCODE_TABLE ;
237285 this .decodeTable = HEX_DECODE_TABLE ;
238286 } else {
@@ -241,7 +289,7 @@ public Base32(final int lineLength, final byte[] lineSeparator, final boolean us
241289 }
242290 if (lineLength > 0 ) {
243291 if (lineSeparator == null ) {
244- throw new IllegalArgumentException ("lineLength " + lineLength + " > 0, but lineSeparator is null" );
292+ throw new IllegalArgumentException ("lineLength " + lineLength + " > 0, but lineSeparator is null" );
245293 }
246294 // Must be done after initializing the tables
247295 if (containsAlphabetOrPad (lineSeparator )) {
@@ -256,6 +304,10 @@ public Base32(final int lineLength, final byte[] lineSeparator, final boolean us
256304 this .lineSeparator = null ;
257305 }
258306 this .decodeSize = this .encodeSize - 1 ;
307+
308+ if (isInAlphabet (pad ) || isWhiteSpace (pad )) {
309+ throw new IllegalArgumentException ("pad must not be in alphabet or whitespace" );
310+ }
259311 }
260312
261313 /**
@@ -292,7 +344,7 @@ void decode(final byte[] in, int inPos, final int inAvail, final Context context
292344 }
293345 for (int i = 0 ; i < inAvail ; i ++) {
294346 final byte b = in [inPos ++];
295- if (b == PAD ) {
347+ if (b == pad ) {
296348 // We're done.
297349 context .eof = true ;
298350 break ;
@@ -398,32 +450,32 @@ void encode(final byte[] in, int inPos, final int inAvail, final Context context
398450 case 1 : // Only 1 octet; take top 5 bits then remainder
399451 buffer [context .pos ++] = encodeTable [(int )(context .lbitWorkArea >> 3 ) & MASK_5BITS ]; // 8-1*5 = 3
400452 buffer [context .pos ++] = encodeTable [(int )(context .lbitWorkArea << 2 ) & MASK_5BITS ]; // 5-3=2
401- buffer [context .pos ++] = PAD ;
402- buffer [context .pos ++] = PAD ;
403- buffer [context .pos ++] = PAD ;
404- buffer [context .pos ++] = PAD ;
405- buffer [context .pos ++] = PAD ;
406- buffer [context .pos ++] = PAD ;
453+ buffer [context .pos ++] = pad ;
454+ buffer [context .pos ++] = pad ;
455+ buffer [context .pos ++] = pad ;
456+ buffer [context .pos ++] = pad ;
457+ buffer [context .pos ++] = pad ;
458+ buffer [context .pos ++] = pad ;
407459 break ;
408460 case 2 : // 2 octets = 16 bits to use
409461 buffer [context .pos ++] = encodeTable [(int )(context .lbitWorkArea >> 11 ) & MASK_5BITS ]; // 16-1*5 = 11
410462 buffer [context .pos ++] = encodeTable [(int )(context .lbitWorkArea >> 6 ) & MASK_5BITS ]; // 16-2*5 = 6
411463 buffer [context .pos ++] = encodeTable [(int )(context .lbitWorkArea >> 1 ) & MASK_5BITS ]; // 16-3*5 = 1
412464 buffer [context .pos ++] = encodeTable [(int )(context .lbitWorkArea << 4 ) & MASK_5BITS ]; // 5-1 = 4
413- buffer [context .pos ++] = PAD ;
414- buffer [context .pos ++] = PAD ;
415- buffer [context .pos ++] = PAD ;
416- buffer [context .pos ++] = PAD ;
465+ buffer [context .pos ++] = pad ;
466+ buffer [context .pos ++] = pad ;
467+ buffer [context .pos ++] = pad ;
468+ buffer [context .pos ++] = pad ;
417469 break ;
418470 case 3 : // 3 octets = 24 bits to use
419471 buffer [context .pos ++] = encodeTable [(int )(context .lbitWorkArea >> 19 ) & MASK_5BITS ]; // 24-1*5 = 19
420472 buffer [context .pos ++] = encodeTable [(int )(context .lbitWorkArea >> 14 ) & MASK_5BITS ]; // 24-2*5 = 14
421473 buffer [context .pos ++] = encodeTable [(int )(context .lbitWorkArea >> 9 ) & MASK_5BITS ]; // 24-3*5 = 9
422474 buffer [context .pos ++] = encodeTable [(int )(context .lbitWorkArea >> 4 ) & MASK_5BITS ]; // 24-4*5 = 4
423475 buffer [context .pos ++] = encodeTable [(int )(context .lbitWorkArea << 1 ) & MASK_5BITS ]; // 5-4 = 1
424- buffer [context .pos ++] = PAD ;
425- buffer [context .pos ++] = PAD ;
426- buffer [context .pos ++] = PAD ;
476+ buffer [context .pos ++] = pad ;
477+ buffer [context .pos ++] = pad ;
478+ buffer [context .pos ++] = pad ;
427479 break ;
428480 case 4 : // 4 octets = 32 bits to use
429481 buffer [context .pos ++] = encodeTable [(int )(context .lbitWorkArea >> 27 ) & MASK_5BITS ]; // 32-1*5 = 27
@@ -433,7 +485,7 @@ void encode(final byte[] in, int inPos, final int inAvail, final Context context
433485 buffer [context .pos ++] = encodeTable [(int )(context .lbitWorkArea >> 7 ) & MASK_5BITS ]; // 32-5*5 = 7
434486 buffer [context .pos ++] = encodeTable [(int )(context .lbitWorkArea >> 2 ) & MASK_5BITS ]; // 32-6*5 = 2
435487 buffer [context .pos ++] = encodeTable [(int )(context .lbitWorkArea << 3 ) & MASK_5BITS ]; // 5-2 = 3
436- buffer [context .pos ++] = PAD ;
488+ buffer [context .pos ++] = pad ;
437489 break ;
438490 default :
439491 throw new IllegalStateException ("Impossible modulus " +context .modulus );
0 commit comments