@@ -111,7 +111,7 @@ public class Base64 extends BaseNCodec {
111111 * Thanks to "commons" project in ws.apache.org for this code.
112112 * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
113113 */
114- private static final byte [] DECODE_TABLE = {
114+ private static final byte [] DEFAULT_DECODE_TABLE = {
115115 // 0 1 2 3 4 5 6 7 8 9 A B C D E F
116116 -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , // 00-0f
117117 -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , // 10-1f
@@ -134,14 +134,18 @@ public class Base64 extends BaseNCodec {
134134 // some state be preserved between calls of encode() and decode().
135135
136136 /**
137- * Encode table to use: either STANDARD or URL_SAFE. Note: the DECODE_TABLE above remains static because it is able
138- * to decode both STANDARD and URL_SAFE streams, but the encodeTable must be a member variable so we can switch
139- * between the two modes.
137+ * Encode table to use: either STANDARD or URL_SAFE or custom.
138+ * Note: the DEFAULT_DECODE_TABLE above remains static for STANDARD and URL_SAFA
139+ * because it is able to decode both STANDARD and URL_SAFE streams,
140+ * but the encodeTable must be a member variable so we can switch
141+ * between modes.
140142 */
141143 private final byte [] encodeTable ;
142144
143- // Only one decode table currently; keep for consistency with Base32 code
144- private final byte [] decodeTable = DECODE_TABLE ;
145+ /**
146+ * Decode table to use
147+ */
148+ private final byte [] decodeTable ;
145149
146150 /**
147151 * Line separator for encoding. Not used when decoding. Only used if lineLength > 0.
@@ -300,6 +304,15 @@ public Base64(final int lineLength, final byte[] lineSeparator, byte[] encodeTab
300304 super (BYTES_PER_UNENCODED_BLOCK , BYTES_PER_ENCODED_BLOCK ,
301305 lineLength ,
302306 lineSeparator == null ? 0 : lineSeparator .length );
307+
308+ this .encodeTable = encodeTable ;
309+
310+ if (encodeTable == STANDARD_ENCODE_TABLE || encodeTable == URL_SAFE_ENCODE_TABLE ) {
311+ decodeTable = DEFAULT_DECODE_TABLE ;
312+ } else {
313+ decodeTable = calculateDecodeTable (encodeTable );
314+ }
315+
303316 // TODO could be simplified if there is no requirement to reject invalid line sep when length <=0
304317 // @see test case Base64Test.testConstructors()
305318 if (lineSeparator != null ) {
@@ -320,7 +333,23 @@ public Base64(final int lineLength, final byte[] lineSeparator, byte[] encodeTab
320333 this .lineSeparator = null ;
321334 }
322335 this .decodeSize = this .encodeSize - 1 ;
323- this .encodeTable = encodeTable ;
336+ }
337+
338+ /**
339+ * calculates a decode table for a given encode table
340+ *
341+ * @param encodeTable
342+ * @return decodeTable
343+ */
344+ private byte [] calculateDecodeTable (byte [] encodeTable ) {
345+ byte [] decodeTable = new byte [256 ];
346+ for (int i =0 ; i < 256 ; i ++) {
347+ decodeTable [i ] = -1 ;
348+ }
349+ for (int i =0 ; i < encodeTable .length ; i ++) {
350+ decodeTable [(int ) encodeTable [i ]] = (byte ) i ;
351+ }
352+ return decodeTable ;
324353 }
325354
326355 /**
@@ -467,8 +496,8 @@ void decode(final byte[] in, int inPos, final int inAvail, final Context context
467496 context .eof = true ;
468497 break ;
469498 }
470- if (b >= 0 && b < DECODE_TABLE .length ) {
471- final int result = DECODE_TABLE [b ];
499+ if (b >= 0 && b < decodeTable .length ) {
500+ final int result = decodeTable [b ];
472501 if (result >= 0 ) {
473502 context .modulus = (context .modulus +1 ) % BYTES_PER_ENCODED_BLOCK ;
474503 context .ibitWorkArea = (context .ibitWorkArea << BITS_PER_ENCODED_BYTE ) + result ;
@@ -535,7 +564,7 @@ public static boolean isArrayByteBase64(final byte[] arrayOctet) {
535564 * @since 1.4
536565 */
537566 public static boolean isBase64 (final byte octet ) {
538- return octet == PAD_DEFAULT || (octet >= 0 && octet < DECODE_TABLE .length && DECODE_TABLE [octet ] != -1 );
567+ return octet == PAD_DEFAULT || (octet >= 0 && octet < DEFAULT_DECODE_TABLE .length && DEFAULT_DECODE_TABLE [octet ] != -1 );
539568 }
540569
541570 /**
0 commit comments