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  /**
21   * Provides Base32 encoding and decoding as defined by <a href="http://www.ietf.org/rfc/rfc4648.txt">RFC 4648</a>.
22   *
23   * <p>
24   * The class can be parameterized in the following manner with various constructors:
25   * </p>
26   * <ul>
27   * <li>Whether to use the "base32hex" variant instead of the default "base32"</li>
28   * <li>Line length: Default 76. Line length that aren't multiples of 8 will still essentially end up being multiples of
29   * 8 in the encoded data.
30   * <li>Line separator: Default is CRLF ("\r\n")</li>
31   * </ul>
32   * <p>
33   * This class operates directly on byte streams, and not character streams.
34   * </p>
35   * <p>
36   * This class is thread-safe.
37   * </p>
38   *
39   * @see <a href="http://www.ietf.org/rfc/rfc4648.txt">RFC 4648</a>
40   *
41   * @since 1.5
42   * @version $Id: Base32.java 1809441 2017-09-23 16:41:53Z ggregory $
43   */
44  public class Base32 extends BaseNCodec {
45  
46      /**
47       * BASE32 characters are 5 bits in length.
48       * They are formed by taking a block of five octets to form a 40-bit string,
49       * which is converted into eight BASE32 characters.
50       */
51      private static final int BITS_PER_ENCODED_BYTE = 5;
52      private static final int BYTES_PER_ENCODED_BLOCK = 8;
53      private static final int BYTES_PER_UNENCODED_BLOCK = 5;
54  
55      /**
56       * Chunk separator per RFC 2045 section 2.1.
57       *
58       * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section 2.1</a>
59       */
60      private static final byte[] CHUNK_SEPARATOR = {'\r', '\n'};
61  
62      /**
63       * This array is a lookup table that translates Unicode characters drawn from the "Base32 Alphabet" (as specified
64       * in Table 3 of RFC 4648) into their 5-bit positive integer equivalents. Characters that are not in the Base32
65       * alphabet but fall within the bounds of the array are translated to -1.
66       */
67      private static final byte[] DECODE_TABLE = {
68           //  0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
69              -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 00-0f
70              -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 10-1f
71              -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 20-2f
72              -1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, -1, -1, -1, // 30-3f 2-7
73              -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, // 40-4f A-O
74              15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,                     // 50-5a P-Z
75                                                          -1, -1, -1, -1, -1, // 5b - 5f
76              -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, // 60 - 6f a-o
77              15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,                     // 70 - 7a p-z/**/
78      };
79  
80      /**
81       * This array is a lookup table that translates 5-bit positive integer index values into their "Base32 Alphabet"
82       * equivalents as specified in Table 3 of RFC 4648.
83       */
84      private static final byte[] ENCODE_TABLE = {
85              'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
86              'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
87              '2', '3', '4', '5', '6', '7',
88      };
89  
90      /**
91       * This array is a lookup table that translates Unicode characters drawn from the "Base32 Hex Alphabet" (as
92       * specified in Table 4 of RFC 4648) into their 5-bit positive integer equivalents. Characters that are not in the
93       * Base32 Hex alphabet but fall within the bounds of the array are translated to -1.
94       */
95      private static final byte[] HEX_DECODE_TABLE = {
96           //  0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
97              -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 00-0f
98              -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 10-1f
99              -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 20-2f
100              0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1, // 30-3f 2-7
101             -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, // 40-4f A-O
102             25, 26, 27, 28, 29, 30, 31,                                     // 50-56 P-V
103                                         -1, -1, -1, -1, -1, -1, -1, -1, -1, // 57-5f Z-_
104             -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, // 60-6f `-o
105             25, 26, 27, 28, 29, 30, 31                                      // 70-76 p-v
106     };
107 
108     /**
109      * This array is a lookup table that translates 5-bit positive integer index values into their
110      * "Base32 Hex Alphabet" equivalents as specified in Table 4 of RFC 4648.
111      */
112     private static final byte[] HEX_ENCODE_TABLE = {
113             '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
114             'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
115             'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
116     };
117 
118     /** Mask used to extract 5 bits, used when encoding Base32 bytes */
119     private static final int MASK_5BITS = 0x1f;
120 
121     // The static final fields above are used for the original static byte[] methods on Base32.
122     // The private member fields below are used with the new streaming approach, which requires
123     // some state be preserved between calls of encode() and decode().
124 
125     /**
126      * Place holder for the bytes we're dealing with for our based logic.
127      * Bitwise operations store and extract the encoding or decoding from this variable.
128      */
129 
130     /**
131      * Convenience variable to help us determine when our buffer is going to run out of room and needs resizing.
132      * <code>decodeSize = {@link #BYTES_PER_ENCODED_BLOCK} - 1 + lineSeparator.length;</code>
133      */
134     private final int decodeSize;
135 
136     /**
137      * Decode table to use.
138      */
139     private final byte[] decodeTable;
140 
141     /**
142      * Convenience variable to help us determine when our buffer is going to run out of room and needs resizing.
143      * <code>encodeSize = {@link #BYTES_PER_ENCODED_BLOCK} + lineSeparator.length;</code>
144      */
145     private final int encodeSize;
146 
147     /**
148      * Encode table to use.
149      */
150     private final byte[] encodeTable;
151 
152     /**
153      * Line separator for encoding. Not used when decoding. Only used if lineLength &gt; 0.
154      */
155     private final byte[] lineSeparator;
156 
157     /**
158      * Creates a Base32 codec used for decoding and encoding.
159      * <p>
160      * When encoding the line length is 0 (no chunking).
161      * </p>
162      *
163      */
164     public Base32() {
165         this(false);
166     }
167 
168     /**
169      * Creates a Base32 codec used for decoding and encoding.
170      * <p>
171      * When encoding the line length is 0 (no chunking).
172      * </p>
173      * @param pad byte used as padding byte.
174      */
175     public Base32(final byte pad) {
176         this(false, pad);
177     }
178 
179     /**
180      * Creates a Base32 codec used for decoding and encoding.
181      * <p>
182      * When encoding the line length is 0 (no chunking).
183      * </p>
184      * @param useHex if {@code true} then use Base32 Hex alphabet
185      */
186     public Base32(final boolean useHex) {
187         this(0, null, useHex, PAD_DEFAULT);
188     }
189 
190     /**
191      * Creates a Base32 codec used for decoding and encoding.
192      * <p>
193      * When encoding the line length is 0 (no chunking).
194      * </p>
195      * @param useHex if {@code true} then use Base32 Hex alphabet
196      * @param pad byte used as padding byte.
197      */
198     public Base32(final boolean useHex, final byte pad) {
199         this(0, null, useHex, pad);
200     }
201 
202     /**
203      * Creates a Base32 codec used for decoding and encoding.
204      * <p>
205      * When encoding the line length is given in the constructor, the line separator is CRLF.
206      * </p>
207      *
208      * @param lineLength
209      *            Each line of encoded data will be at most of the given length (rounded down to nearest multiple of
210      *            8). If lineLength &lt;= 0, then the output will not be divided into lines (chunks). Ignored when
211      *            decoding.
212      */
213     public Base32(final int lineLength) {
214         this(lineLength, CHUNK_SEPARATOR);
215     }
216 
217     /**
218      * Creates a Base32 codec used for decoding and encoding.
219      * <p>
220      * When encoding the line length and line separator are given in the constructor.
221      * </p>
222      * <p>
223      * Line lengths that aren't multiples of 8 will still essentially end up being multiples of 8 in the encoded data.
224      * </p>
225      *
226      * @param lineLength
227      *            Each line of encoded data will be at most of the given length (rounded down to nearest multiple of
228      *            8). If lineLength &lt;= 0, then the output will not be divided into lines (chunks). Ignored when
229      *            decoding.
230      * @param lineSeparator
231      *            Each line of encoded data will end with this sequence of bytes.
232      * @throws IllegalArgumentException
233      *             The provided lineSeparator included some Base32 characters. That's not going to work!
234      */
235     public Base32(final int lineLength, final byte[] lineSeparator) {
236         this(lineLength, lineSeparator, false, PAD_DEFAULT);
237     }
238 
239     /**
240      * Creates a Base32 / Base32 Hex codec used for decoding and encoding.
241      * <p>
242      * When encoding the line length and line separator are given in the constructor.
243      * </p>
244      * <p>
245      * Line lengths that aren't multiples of 8 will still essentially end up being multiples of 8 in the encoded data.
246      * </p>
247      *
248      * @param lineLength
249      *            Each line of encoded data will be at most of the given length (rounded down to nearest multiple of
250      *            8). If lineLength &lt;= 0, then the output will not be divided into lines (chunks). Ignored when
251      *            decoding.
252      * @param lineSeparator
253      *            Each line of encoded data will end with this sequence of bytes.
254      * @param useHex
255      *            if {@code true}, then use Base32 Hex alphabet, otherwise use Base32 alphabet
256      * @throws IllegalArgumentException
257      *             The provided lineSeparator included some Base32 characters. That's not going to work! Or the
258      *             lineLength &gt; 0 and lineSeparator is null.
259      */
260     public Base32(final int lineLength, final byte[] lineSeparator, final boolean useHex) {
261         this(lineLength, lineSeparator, useHex, PAD_DEFAULT);
262     }
263 
264     /**
265      * Creates a Base32 / Base32 Hex codec used for decoding and encoding.
266      * <p>
267      * When encoding the line length and line separator are given in the constructor.
268      * </p>
269      * <p>
270      * Line lengths that aren't multiples of 8 will still essentially end up being multiples of 8 in the encoded data.
271      * </p>
272      *
273      * @param lineLength
274      *            Each line of encoded data will be at most of the given length (rounded down to nearest multiple of
275      *            8). If lineLength &lt;= 0, then the output will not be divided into lines (chunks). Ignored when
276      *            decoding.
277      * @param lineSeparator
278      *            Each line of encoded data will end with this sequence of bytes.
279      * @param useHex
280      *            if {@code true}, then use Base32 Hex alphabet, otherwise use Base32 alphabet
281      * @param pad byte used as padding byte.
282      * @throws IllegalArgumentException
283      *             The provided lineSeparator included some Base32 characters. That's not going to work! Or the
284      *             lineLength &gt; 0 and lineSeparator is null.
285      */
286     public Base32(final int lineLength, final byte[] lineSeparator, final boolean useHex, final byte pad) {
287         super(BYTES_PER_UNENCODED_BLOCK, BYTES_PER_ENCODED_BLOCK, lineLength,
288                 lineSeparator == null ? 0 : lineSeparator.length, pad);
289         if (useHex) {
290             this.encodeTable = HEX_ENCODE_TABLE;
291             this.decodeTable = HEX_DECODE_TABLE;
292         } else {
293             this.encodeTable = ENCODE_TABLE;
294             this.decodeTable = DECODE_TABLE;
295         }
296         if (lineLength > 0) {
297             if (lineSeparator == null) {
298                 throw new IllegalArgumentException("lineLength " + lineLength + " > 0, but lineSeparator is null");
299             }
300             // Must be done after initializing the tables
301             if (containsAlphabetOrPad(lineSeparator)) {
302                 final String sep = StringUtils.newStringUtf8(lineSeparator);
303                 throw new IllegalArgumentException("lineSeparator must not contain Base32 characters: [" + sep + "]");
304             }
305             this.encodeSize = BYTES_PER_ENCODED_BLOCK + lineSeparator.length;
306             this.lineSeparator = new byte[lineSeparator.length];
307             System.arraycopy(lineSeparator, 0, this.lineSeparator, 0, lineSeparator.length);
308         } else {
309             this.encodeSize = BYTES_PER_ENCODED_BLOCK;
310             this.lineSeparator = null;
311         }
312         this.decodeSize = this.encodeSize - 1;
313 
314         if (isInAlphabet(pad) || isWhiteSpace(pad)) {
315             throw new IllegalArgumentException("pad must not be in alphabet or whitespace");
316         }
317     }
318 
319     /**
320      * <p>
321      * Decodes all of the provided data, starting at inPos, for inAvail bytes. Should be called at least twice: once
322      * with the data to decode, and once with inAvail set to "-1" to alert decoder that EOF has been reached. The "-1"
323      * call is not necessary when decoding, but it doesn't hurt, either.
324      * </p>
325      * <p>
326      * Ignores all non-Base32 characters. This is how chunked (e.g. 76 character) data is handled, since CR and LF are
327      * silently ignored, but has implications for other bytes, too. This method subscribes to the garbage-in,
328      * garbage-out philosophy: it will not check the provided data for validity.
329      * </p>
330      *
331      * @param in
332      *            byte[] array of ascii data to Base32 decode.
333      * @param inPos
334      *            Position to start reading data from.
335      * @param inAvail
336      *            Amount of bytes available from input for encoding.
337      * @param context the context to be used
338      *
339      * Output is written to {@link Context#buffer} as 8-bit octets, using {@link Context#pos} as the buffer position
340      */
341     @Override
342     void decode(final byte[] in, int inPos, final int inAvail, final Context context) {
343         // package protected for access from I/O streams
344 
345         if (context.eof) {
346             return;
347         }
348         if (inAvail < 0) {
349             context.eof = true;
350         }
351         for (int i = 0; i < inAvail; i++) {
352             final byte b = in[inPos++];
353             if (b == pad) {
354                 // We're done.
355                 context.eof = true;
356                 break;
357             }
358             final byte[] buffer = ensureBufferSize(decodeSize, context);
359             if (b >= 0 && b < this.decodeTable.length) {
360                 final int result = this.decodeTable[b];
361                 if (result >= 0) {
362                     context.modulus = (context.modulus+1) % BYTES_PER_ENCODED_BLOCK;
363                     // collect decoded bytes
364                     context.lbitWorkArea = (context.lbitWorkArea << BITS_PER_ENCODED_BYTE) + result;
365                     if (context.modulus == 0) { // we can output the 5 bytes
366                         buffer[context.pos++] = (byte) ((context.lbitWorkArea >> 32) & MASK_8BITS);
367                         buffer[context.pos++] = (byte) ((context.lbitWorkArea >> 24) & MASK_8BITS);
368                         buffer[context.pos++] = (byte) ((context.lbitWorkArea >> 16) & MASK_8BITS);
369                         buffer[context.pos++] = (byte) ((context.lbitWorkArea >> 8) & MASK_8BITS);
370                         buffer[context.pos++] = (byte) (context.lbitWorkArea & MASK_8BITS);
371                     }
372                 }
373             }
374         }
375 
376         // Two forms of EOF as far as Base32 decoder is concerned: actual
377         // EOF (-1) and first time '=' character is encountered in stream.
378         // This approach makes the '=' padding characters completely optional.
379         if (context.eof && context.modulus >= 2) { // if modulus < 2, nothing to do
380             final byte[] buffer = ensureBufferSize(decodeSize, context);
381 
382             //  we ignore partial bytes, i.e. only multiples of 8 count
383             switch (context.modulus) {
384                 case 2 : // 10 bits, drop 2 and output one byte
385                     buffer[context.pos++] = (byte) ((context.lbitWorkArea >> 2) & MASK_8BITS);
386                     break;
387                 case 3 : // 15 bits, drop 7 and output 1 byte
388                     buffer[context.pos++] = (byte) ((context.lbitWorkArea >> 7) & MASK_8BITS);
389                     break;
390                 case 4 : // 20 bits = 2*8 + 4
391                     context.lbitWorkArea = context.lbitWorkArea >> 4; // drop 4 bits
392                     buffer[context.pos++] = (byte) ((context.lbitWorkArea >> 8) & MASK_8BITS);
393                     buffer[context.pos++] = (byte) ((context.lbitWorkArea) & MASK_8BITS);
394                     break;
395                 case 5 : // 25bits = 3*8 + 1
396                     context.lbitWorkArea = context.lbitWorkArea >> 1;
397                     buffer[context.pos++] = (byte) ((context.lbitWorkArea >> 16) & MASK_8BITS);
398                     buffer[context.pos++] = (byte) ((context.lbitWorkArea >> 8) & MASK_8BITS);
399                     buffer[context.pos++] = (byte) ((context.lbitWorkArea) & MASK_8BITS);
400                     break;
401                 case 6 : // 30bits = 3*8 + 6
402                     context.lbitWorkArea = context.lbitWorkArea >> 6;
403                     buffer[context.pos++] = (byte) ((context.lbitWorkArea >> 16) & MASK_8BITS);
404                     buffer[context.pos++] = (byte) ((context.lbitWorkArea >> 8) & MASK_8BITS);
405                     buffer[context.pos++] = (byte) ((context.lbitWorkArea) & MASK_8BITS);
406                     break;
407                 case 7 : // 35 = 4*8 +3
408                     context.lbitWorkArea = context.lbitWorkArea >> 3;
409                     buffer[context.pos++] = (byte) ((context.lbitWorkArea >> 24) & MASK_8BITS);
410                     buffer[context.pos++] = (byte) ((context.lbitWorkArea >> 16) & MASK_8BITS);
411                     buffer[context.pos++] = (byte) ((context.lbitWorkArea >> 8) & MASK_8BITS);
412                     buffer[context.pos++] = (byte) ((context.lbitWorkArea) & MASK_8BITS);
413                     break;
414                 default:
415                     // modulus can be 0-7, and we excluded 0,1 already
416                     throw new IllegalStateException("Impossible modulus "+context.modulus);
417             }
418         }
419     }
420 
421     /**
422      * <p>
423      * Encodes all of the provided data, starting at inPos, for inAvail bytes. Must be called at least twice: once with
424      * the data to encode, and once with inAvail set to "-1" to alert encoder that EOF has been reached, so flush last
425      * remaining bytes (if not multiple of 5).
426      * </p>
427      *
428      * @param in
429      *            byte[] array of binary data to Base32 encode.
430      * @param inPos
431      *            Position to start reading data from.
432      * @param inAvail
433      *            Amount of bytes available from input for encoding.
434      * @param context the context to be used
435      */
436     @Override
437     void encode(final byte[] in, int inPos, final int inAvail, final Context context) {
438         // package protected for access from I/O streams
439 
440         if (context.eof) {
441             return;
442         }
443         // inAvail < 0 is how we're informed of EOF in the underlying data we're
444         // encoding.
445         if (inAvail < 0) {
446             context.eof = true;
447             if (0 == context.modulus && lineLength == 0) {
448                 return; // no leftovers to process and not using chunking
449             }
450             final byte[] buffer = ensureBufferSize(encodeSize, context);
451             final int savedPos = context.pos;
452             switch (context.modulus) { // % 5
453                 case 0 :
454                     break;
455                 case 1 : // Only 1 octet; take top 5 bits then remainder
456                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea >> 3) & MASK_5BITS]; // 8-1*5 = 3
457                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea << 2) & MASK_5BITS]; // 5-3=2
458                     buffer[context.pos++] = pad;
459                     buffer[context.pos++] = pad;
460                     buffer[context.pos++] = pad;
461                     buffer[context.pos++] = pad;
462                     buffer[context.pos++] = pad;
463                     buffer[context.pos++] = pad;
464                     break;
465                 case 2 : // 2 octets = 16 bits to use
466                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea >> 11) & MASK_5BITS]; // 16-1*5 = 11
467                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea >>  6) & MASK_5BITS]; // 16-2*5 = 6
468                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea >>  1) & MASK_5BITS]; // 16-3*5 = 1
469                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea <<  4) & MASK_5BITS]; // 5-1 = 4
470                     buffer[context.pos++] = pad;
471                     buffer[context.pos++] = pad;
472                     buffer[context.pos++] = pad;
473                     buffer[context.pos++] = pad;
474                     break;
475                 case 3 : // 3 octets = 24 bits to use
476                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea >> 19) & MASK_5BITS]; // 24-1*5 = 19
477                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea >> 14) & MASK_5BITS]; // 24-2*5 = 14
478                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea >>  9) & MASK_5BITS]; // 24-3*5 = 9
479                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea >>  4) & MASK_5BITS]; // 24-4*5 = 4
480                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea <<  1) & MASK_5BITS]; // 5-4 = 1
481                     buffer[context.pos++] = pad;
482                     buffer[context.pos++] = pad;
483                     buffer[context.pos++] = pad;
484                     break;
485                 case 4 : // 4 octets = 32 bits to use
486                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea >> 27) & MASK_5BITS]; // 32-1*5 = 27
487                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea >> 22) & MASK_5BITS]; // 32-2*5 = 22
488                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea >> 17) & MASK_5BITS]; // 32-3*5 = 17
489                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea >> 12) & MASK_5BITS]; // 32-4*5 = 12
490                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea >>  7) & MASK_5BITS]; // 32-5*5 =  7
491                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea >>  2) & MASK_5BITS]; // 32-6*5 =  2
492                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea <<  3) & MASK_5BITS]; // 5-2 = 3
493                     buffer[context.pos++] = pad;
494                     break;
495                 default:
496                     throw new IllegalStateException("Impossible modulus "+context.modulus);
497             }
498             context.currentLinePos += context.pos - savedPos; // keep track of current line position
499             // if currentPos == 0 we are at the start of a line, so don't add CRLF
500             if (lineLength > 0 && context.currentLinePos > 0){ // add chunk separator if required
501                 System.arraycopy(lineSeparator, 0, buffer, context.pos, lineSeparator.length);
502                 context.pos += lineSeparator.length;
503             }
504         } else {
505             for (int i = 0; i < inAvail; i++) {
506                 final byte[] buffer = ensureBufferSize(encodeSize, context);
507                 context.modulus = (context.modulus+1) % BYTES_PER_UNENCODED_BLOCK;
508                 int b = in[inPos++];
509                 if (b < 0) {
510                     b += 256;
511                 }
512                 context.lbitWorkArea = (context.lbitWorkArea << 8) + b; // BITS_PER_BYTE
513                 if (0 == context.modulus) { // we have enough bytes to create our output
514                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea >> 35) & MASK_5BITS];
515                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea >> 30) & MASK_5BITS];
516                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea >> 25) & MASK_5BITS];
517                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea >> 20) & MASK_5BITS];
518                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea >> 15) & MASK_5BITS];
519                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea >> 10) & MASK_5BITS];
520                     buffer[context.pos++] = encodeTable[(int)(context.lbitWorkArea >> 5) & MASK_5BITS];
521                     buffer[context.pos++] = encodeTable[(int)context.lbitWorkArea & MASK_5BITS];
522                     context.currentLinePos += BYTES_PER_ENCODED_BLOCK;
523                     if (lineLength > 0 && lineLength <= context.currentLinePos) {
524                         System.arraycopy(lineSeparator, 0, buffer, context.pos, lineSeparator.length);
525                         context.pos += lineSeparator.length;
526                         context.currentLinePos = 0;
527                     }
528                 }
529             }
530         }
531     }
532 
533     /**
534      * Returns whether or not the {@code octet} is in the Base32 alphabet.
535      *
536      * @param octet
537      *            The value to test
538      * @return {@code true} if the value is defined in the the Base32 alphabet {@code false} otherwise.
539      */
540     @Override
541     public boolean isInAlphabet(final byte octet) {
542         return octet >= 0 && octet < decodeTable.length && decodeTable[octet] != -1;
543     }
544 }