FileDocCategorySizeDatePackage
Base64.javaAPI DocApache Axis 1.48864Sat Apr 22 18:57:26 BST 2006org.apache.axis.utils

Base64

public final class Base64 extends Object
Unceremoniously lifted from jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/Base64.java Revision 1.8 2002/01/05 11:15:59 Eliminates dependency on sun.misc.Base64Encoding, which isn't appreciated by the J2EE security manager. (it's an access exception to load sun.misc.* classes in application code).

Base64 encoder and decoder.

This class provides encoding/decoding methods for the Base64 encoding as defined by RFC 2045, N. Freed and N. Borenstein. RFC 2045: Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies. Reference 1996. Available at: http://www.ietf.org/rfc/rfc2045.txt

author
Jeffrey Rodriguez

Fields Summary
private static final int
BASELENGTH
private static final int
LOOKUPLENGTH
private static final int
TWENTYFOURBITGROUP
private static final int
EIGHTBIT
private static final int
SIXTEENBIT
private static final int
SIXBIT
private static final int
FOURBYTE
private static final int
SIGN
private static final byte
PAD
private static byte[]
base64Alphabet
private static byte[]
lookUpBase64Alphabet
Constructors Summary
Methods Summary
static byte[]decode(byte[] base64Data)
Decodes Base64 data into octects

param
base64Data Byte array containing Base64 data
return
Array containing decoded data.

        // Should we throw away anything not in base64Data ?

        // handle the edge case, so we don't have to worry about it later
        if(base64Data.length == 0) { return new byte[0]; }

        int      numberQuadruple    = base64Data.length/FOURBYTE;
        byte     decodedData[]      = null;
        byte     b1=0,b2=0,b3=0, b4=0, marker0=0, marker1=0;

        int encodedIndex = 0;
        int dataIndex    = 0;
        {
            // this block sizes the output array properly - rlw
            int lastData = base64Data.length;
            // ignore the '=' padding
            while(base64Data[lastData-1] == PAD) {
                if(--lastData == 0) { return new byte[0]; }
            }
            decodedData = new byte[ lastData - numberQuadruple ];
        }

        for (int i = 0; i<numberQuadruple; i++ ) {
            dataIndex = i*4;
            marker0   = base64Data[dataIndex +2];
            marker1   = base64Data[dataIndex +3];

            b1 = base64Alphabet[base64Data[dataIndex]];
            b2 = base64Alphabet[base64Data[dataIndex +1]];

            if ( marker0 != PAD && marker1 != PAD ) {     //No PAD e.g 3cQl
                b3 = base64Alphabet[ marker0 ];
                b4 = base64Alphabet[ marker1 ];

                decodedData[encodedIndex]   = (byte)(  b1 <<2 | b2>>4 ) ;
                decodedData[encodedIndex+1] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) );
                decodedData[encodedIndex+2] = (byte)( b3<<6 | b4 );
            } else if ( marker0 == PAD ) {               //Two PAD e.g. 3c[Pad][Pad]
                decodedData[encodedIndex]   = (byte)(  b1 <<2 | b2>>4 ) ;
            } else if ( marker1 == PAD ) {              //One PAD e.g. 3cQ[Pad]
                b3 = base64Alphabet[ marker0 ];

                decodedData[encodedIndex]   = (byte)(  b1 <<2 | b2>>4 );
                decodedData[encodedIndex+1] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) );
            }
            encodedIndex += 3;
        }
        return decodedData;
    
static byte[]encode(byte[] binaryData)
Encodes hex octects into Base64

param
binaryData Array containing binaryData
return
Base64-encoded array


        int      lengthDataBits    = binaryData.length*EIGHTBIT;
        int      fewerThan24bits   = lengthDataBits%TWENTYFOURBITGROUP;
        int      numberTriplets    = lengthDataBits/TWENTYFOURBITGROUP;
        byte     encodedData[]     = null;


        if ( fewerThan24bits != 0 ) {
            //data not divisible by 24 bit
            encodedData = new byte[ (numberTriplets + 1 )*4  ];
        }
        else {
            // 16 or 8 bit
            encodedData = new byte[ numberTriplets*4 ];
        }

        byte k=0, l=0, b1=0,b2=0,b3=0;

        int encodedIndex = 0;
        int dataIndex   = 0;
        int i           = 0;
        for ( i = 0; i<numberTriplets; i++ ) {

            dataIndex = i*3;
            b1 = binaryData[dataIndex];
            b2 = binaryData[dataIndex + 1];
            b3 = binaryData[dataIndex + 2];

            l  = (byte)(b2 & 0x0f);
            k  = (byte)(b1 & 0x03);

            encodedIndex = i*4;
            byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0);

            byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0);
            byte val3 = ((b3 & SIGN)==0)?(byte)(b3>>6):(byte)((b3)>>6^0xfc);

            encodedData[encodedIndex]   = lookUpBase64Alphabet[ val1 ];
            encodedData[encodedIndex+1] = lookUpBase64Alphabet[ val2 | ( k<<4 )];
            encodedData[encodedIndex+2] = lookUpBase64Alphabet[ (l <<2 ) | val3 ];
            encodedData[encodedIndex+3] = lookUpBase64Alphabet[ b3 & 0x3f ];
        }

        // form integral number of 6-bit groups
        dataIndex    = i*3;
        encodedIndex = i*4;
        if (fewerThan24bits == EIGHTBIT ) {
            b1 = binaryData[dataIndex];
            k = (byte) ( b1 &0x03 );
            byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0);
            encodedData[encodedIndex]     = lookUpBase64Alphabet[ val1 ];
            encodedData[encodedIndex + 1] = lookUpBase64Alphabet[ k<<4 ];
            encodedData[encodedIndex + 2] = PAD;
            encodedData[encodedIndex + 3] = PAD;
        } else if ( fewerThan24bits == SIXTEENBIT ) {
            b1 = binaryData[dataIndex];
            b2 = binaryData[dataIndex +1 ];
            l = ( byte ) ( b2 &0x0f );
            k = ( byte ) ( b1 &0x03 );

            byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0);
            byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0);

            encodedData[encodedIndex]     = lookUpBase64Alphabet[ val1 ];
            encodedData[encodedIndex + 1] = lookUpBase64Alphabet[ val2 | ( k<<4 )];
            encodedData[encodedIndex + 2] = lookUpBase64Alphabet[ l<<2 ];
            encodedData[encodedIndex + 3] = PAD;
        }
        return encodedData;
    
static booleanisArrayByteBase64(byte[] arrayOctect)

        int length = arrayOctect.length;
        if ( length == 0 ) {
            return true;
        }
        for ( int i=0; i < length; i++ ) {
            if ( Base64.isBase64( arrayOctect[i] ) == false) {
                return false;
            }
        }
        return true;
    
static booleanisBase64(java.lang.String isValidString)


     

        for (int i = 0; i<BASELENGTH; i++ ) {
            base64Alphabet[i] = -1;
        }
        for ( int i = 'Z"; i >= 'A"; i-- ) {
            base64Alphabet[i] = (byte) (i-'A");
        }
        for ( int i = 'z"; i>= 'a"; i--) {
            base64Alphabet[i] = (byte) ( i-'a" + 26);
        }

        for ( int i = '9"; i >= '0"; i--) {
            base64Alphabet[i] = (byte) (i-'0" + 52);
        }

        base64Alphabet['+"]  = 62;
        base64Alphabet['/"]  = 63;

        for (int i = 0; i<=25; i++ ) {
            lookUpBase64Alphabet[i] = (byte) ('A"+i );
        }

        for (int i = 26,  j = 0; i<=51; i++, j++ ) {
            lookUpBase64Alphabet[i] = (byte) ('a"+ j );
        }

        for (int i = 52,  j = 0; i<=61; i++, j++ ) {
            lookUpBase64Alphabet[i] = (byte) ('0" + j );
        }
        lookUpBase64Alphabet[62] = (byte) '+";
        lookUpBase64Alphabet[63] = (byte) '/";

    
        return( isArrayByteBase64( isValidString.getBytes()));
    
static booleanisBase64(byte octect)

        // Should we ignore white space?
        return(octect == PAD || base64Alphabet[octect] != -1 );