Mega Code Archive

 
Categories / Java Tutorial / Development
 

Encodedecode for RFC 2045 Base64 as defined by RFC 2045

/*  * Licensed to the Apache Software Foundation (ASF) under one or more  * contributor license agreements.  See the NOTICE file distributed with  * this work for additional information regarding copyright ownership.  * The ASF licenses this file to You 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.  */ /**  * This class provides encode/decode for RFC 2045 Base64 as defined by  * RFC 2045, N. Freed and N. Borenstein.  <a  * href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>:  * Multipurpose Internet Mail Extensions (MIME) Part One: Format of  * Internet Message Bodies. Reference 1996  *  * @author Jeffrey Rodriguez  * @version $Id: Base64.java 515 2008-03-17 21:02:23Z jfrederic.clere@jboss.com $  */ public final class  Base64 {     static private final int  BASELENGTH         = 255;     static private final int  LOOKUPLENGTH       = 64;     static private final int  TWENTYFOURBITGROUP = 24;     static private final int  EIGHTBIT           = 8;     static private final int  SIXTEENBIT         = 16;     static private final int  SIXBIT             = 6;     static private final int  FOURBYTE           = 4;     static private final int  SIGN               = -128;     static private final byte PAD                = (byte) '=';     static private byte [] base64Alphabet       = new byte[BASELENGTH];     static private byte [] lookUpBase64Alphabet = new byte[LOOKUPLENGTH];     //static private final Log log = LogSource.getInstance("org.apache.commons.util.Base64");     static     {         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) '/';     }     public static boolean isBase64( String isValidString )     {         return isArrayByteBase64(isValidString.getBytes());     }     public static boolean isBase64( byte octect )     {         //shall we ignore white space? JEFF??         return (octect == PAD || base64Alphabet[octect] != -1);     }     public static boolean isArrayByteBase64( byte[] arrayOctect )     {         int length = arrayOctect.length;         if (length == 0)         {             // shouldn't a 0 length array be valid base64 data?             // return false;             return true;         }         for (int i=0; i < length; i++)         {             if ( !Base64.isBase64(arrayOctect[i]) )                 return false;         }         return true;     }     /**      * Encodes hex octects into Base64.      *      * @param binaryData Array containing binary data to encode.      * @return Base64-encoded data.      */     public static byte[] encode( byte[] binaryData )     {         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;         //log.debug("number of triplets = " + numberTriplets);         for ( i = 0; i<numberTriplets; i++ )         {             dataIndex = i*3;             b1 = binaryData[dataIndex];             b2 = binaryData[dataIndex + 1];             b3 = binaryData[dataIndex + 2];             //log.debug("b1= " + b1 +", b2= " + b2 + ", b3= " + b3);             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 ];             //log.debug( "val2 = " + val2 );             //log.debug( "k4   = " + (k<<4) );             //log.debug(  "vak  = " + (val2 | (k<<4)) );             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 );             //log.debug("b1=" + b1);             //log.debug("b1<<2 = " + (b1>>2) );             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;     } }