/*
* This file is part of muCommander, http://www.mucommander.com
* Copyright (C) 2002-2016 Maxence Bernard
*
* muCommander is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* muCommander is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.mucommander.commons.io.base64;
/**
* This class represents an immutable Base64 encoding/decoding table. It provides the correspondance between encoded
* and decoded characters (and vice-versa), and the character to use for padding.
* <p>
* A number of common Base64 tables are provided as public static final fields of this class:
* <ul>
* <li>{@link #STANDARD_TABLE}</li>
* <li>{@link #URL_SAFE_TABLE}</li>
* <li>{@link #FILENAME_SAFE_TABLE}</li>
* <li>{@link #REGEXP_SAFE_TABLE}</li>
* </ul>
* </p>
* @author Maxence Bernard
*/
public class Base64Table {
/** Encoding table, 64 bytes long */
protected byte[] encodingTable;
/** Decoding table, 256 bytes long */
protected int[] decodingTable;
/** Padding character used */
protected byte paddingChar;
/** The standard Base64 table, using '+' and '/' for non-alphanumerical characters, and '=' for padding */
public final static Base64Table STANDARD_TABLE = createTable((byte)'+', (byte)'/', (byte)'=');
/** An URL-safe Base64 table, using '-' and '_' for non-alphanumerical characters, and '.' for padding */
public final static Base64Table URL_SAFE_TABLE = createTable((byte)'-', (byte)'_', (byte)'.');
/** A filename-safe Base64 table, using '+' and '-' for non-alphanumerical characters, and '=' for padding */
public final static Base64Table FILENAME_SAFE_TABLE = createTable((byte)'+', (byte)'-', (byte)'=');
/** A regexp-safe Base64 table, using '!' and '-' for non-alphanumerical characters, and '=' for padding */
public final static Base64Table REGEXP_SAFE_TABLE = createTable((byte)'!', (byte)'-', (byte)'=');
/**
* Creates a base64 table using A–Z, a–z, and 0–9 for the first 62 values, the two specified characters at
* position 62 and 63 in the table, and the specified padding character.
*
* @param char62 ASCII character to use at position 62 of the table
* @param char63 ASCII character to use at position 63 of the table
* @param paddingChar ASCII character to use for padding
* @throws IllegalArgumentException if one specified characters are the same or alphanumerical characters
* @return a base64 table
*/
public static Base64Table createTable(byte char62, byte char63, byte paddingChar) throws IllegalArgumentException {
byte[] table = new byte[] {
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
'w','x','y','z','0','1','2','3','4','5','6','7','8','9',char62,char63
};
return new Base64Table(table, paddingChar);
}
/**
* Creates a new <code>Base64Table</code> using the specified character table and padding character.
*
* <p>An <code>IllegalArgumentException</code> if the specified table is not 64 bytes long, contains duplicate
* values, or if the specified padding character is present in the table.</p>
*
* <p>The given byte array is cloned before being stored, to avoid any side effect that could be caused by the
* byte array being modified inadvertently after this constructor is called.</p>
*
* @param table the base64 character table. The array must be 64 bytes long and must not contain any duplicate values.
* @param paddingChar the ASCII character used for padding. This character must not already be used in the table.
* @throws IllegalArgumentException if the specified table is not 64 bytes long, contains duplicate values, or
* if the specified padding character is present in the table.
*/
public Base64Table(byte[] table, byte paddingChar) throws IllegalArgumentException {
// Basic length check
if(table==null || table.length!=64)
throw new IllegalArgumentException("Base64 table is not 64 bytes long");
// Create the decoding table and initialize all values to -1
this.decodingTable = new int[256];
char c;
for(c=0; c<256; c++)
decodingTable[c] = -1;
// Fill the decoding table and snsure that characters are used only once
byte val;
for(int i=0; i<64; i++) {
val= table[i];
if(decodingTable[val]!=-1)
throw new IllegalArgumentException("Base64 table contains duplicate values");
decodingTable[val] = i;
}
// Ensure that the padding character is not already used in the table
if(decodingTable[paddingChar]!=-1)
throw new IllegalArgumentException("Padding char is already used in Base64 table");
this.paddingChar = paddingChar;
// Clone the byte array so that it cannot be altered externally
this.encodingTable = new byte[64];
System.arraycopy(table, 0, this.encodingTable, 0, 64);
}
/**
* Returns the base64 encoding table. The return array should not be modified.
*
* @return the base64 encoding table.
*/
byte[] getEncodingTable() {
return encodingTable;
}
/**
* Returns the base64 decoding table, containing byte values with the exception of <code>-1</code> which indicates
* the character is not used. The return array should not be modified.
*
* @return the base64 decoding table.
*/
int[] getDecodingTable() {
return decodingTable;
}
/**
* Returns the ASCII character used for padding.
*
* @return the ASCII character used for padding.
*/
public byte getPaddingChar() {
return paddingChar;
}
}