/* * Copyright 2009 Alin Dreghiciu. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. * * See the License for the specific language governing permissions and * limitations under the License. */ package org.qi4j.api.util; /** * Base64Encoder. */ public final class Base64Encoder { /** * Utility class. ment to be used via static methods. */ private Base64Encoder() { // utility class } /** * Encodes a String into a base 64 String. The resulting encoding is chunked at 76 bytes. * * @param s String to encode. * * @return encoded string. */ public static String encode( String s, boolean includePadding ) { byte[] sBytes = s.getBytes(); sBytes = encode( sBytes, includePadding ); s = new String( sBytes ); return s; } /** * Decodes a base 64 String into a String. * * @param s String to decode. * * @return encoded string. * * @throws java.lang.IllegalArgumentException * _ If the given byte array was not valid base64 encoding. */ public static String decode( String s ) throws IllegalArgumentException { s = s.replaceAll( "\n", "" ); s = s.replaceAll( "\r", "" ); byte[] sBytes = s.getBytes(); sBytes = decode( sBytes ); s = new String( sBytes ); return s; } private static final byte[] ALPHASET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".getBytes(); private static final int I6O2 = 255 - 3; private static final int O6I2 = 3; private static final int I4O4 = 255 - 15; private static final int O4I4 = 15; private static final int I2O6 = 255 - 63; private static final int O2I6 = 63; /** * Encodes a byte array into a base 64 byte array. * * @param dData byte array to encode. * * @return encoded byte array. */ public static byte[] encode( byte[] dData, boolean includePadding ) { if( dData == null ) { throw new IllegalArgumentException( "Cannot encode null" ); } byte[] eData = new byte[ ( ( dData.length + 2 ) / 3 ) * 4 ]; int eIndex = 0; for( int i = 0; i < dData.length; i += 3 ) { int d1; int d2 = 0; int d3 = 0; int e1; int e2; int e3; int e4; int pad = 0; d1 = dData[ i ]; if( ( i + 1 ) < dData.length ) { d2 = dData[ i + 1 ]; if( ( i + 2 ) < dData.length ) { d3 = dData[ i + 2 ]; } else { pad = 1; } } else { pad = 2; } e1 = ALPHASET[ ( d1 & I6O2 ) >> 2 ]; e2 = ALPHASET[ ( d1 & O6I2 ) << 4 | ( d2 & I4O4 ) >> 4 ]; e3 = ALPHASET[ ( d2 & O4I4 ) << 2 | ( d3 & I2O6 ) >> 6 ]; e4 = ALPHASET[ ( d3 & O2I6 ) ]; eData[ eIndex++ ] = (byte) e1; eData[ eIndex++ ] = (byte) e2; eData[ eIndex++ ] = ( pad < 2 ) ? (byte) e3 : (byte) '='; eData[ eIndex++ ] = ( pad < 1 ) ? (byte) e4 : (byte) '='; if( pad > 0 && !includePadding ) { byte[] neweData = new byte[ eData.length - pad ]; System.arraycopy( eData, 0, neweData, 0, eIndex - pad ); eData = neweData; } } return eData; } private final static int[] CODES = new int[ 256 ]; static { for( int i = 0; i < CODES.length; i++ ) { CODES[ i ] = 64; } for( int i = 0; i < ALPHASET.length; i++ ) { CODES[ ALPHASET[ i ] ] = i; } } /** * Decodes a base64 byte array into a byte array. * <p> * * @param eData byte array to decode. * * @return decoded byte array. * * @throws java.lang.IllegalArgumentException * thrown if the given byte array was not valid com.sun.syndication.io.impl.Base64 encoding. */ public static byte[] decode( byte[] eData ) { if( eData == null ) { throw new IllegalArgumentException( "Cannot decode null" ); } byte[] cleanEData = eData.clone(); int cleanELength = 0; for( byte anEData : eData ) { if( anEData < 256 && CODES[ anEData ] < 64 ) { cleanEData[ cleanELength++ ] = anEData; } } int dLength = ( cleanELength / 4 ) * 3; switch( cleanELength % 4 ) { case 3: dLength += 2; break; case 2: dLength++; break; } byte[] dData = new byte[ dLength ]; int dIndex = 0; for( int i = 0; i < eData.length; i += 4 ) { if( ( i + 3 ) > eData.length ) { throw new IllegalArgumentException( "byte array is not a valid base64 encoding" ); } int e1 = CODES[ cleanEData[ i ] ]; int e2 = CODES[ cleanEData[ i + 1 ] ]; int e3 = CODES[ cleanEData[ i + 2 ] ]; int e4 = CODES[ cleanEData[ i + 3 ] ]; dData[ dIndex++ ] = (byte) ( ( e1 << 2 ) | ( e2 >> 4 ) ); if( dIndex < dData.length ) { dData[ dIndex++ ] = (byte) ( ( e2 << 4 ) | ( e3 >> 2 ) ); } if( dIndex < dData.length ) { dData[ dIndex++ ] = (byte) ( ( e3 << 6 ) | ( e4 ) ); } } return dData; } }