KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > axis > utils > Base64


1 /*
2  * Copyright 1999,2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.axis.utils;
18
19 /**
20  * Unceremoniously lifted from
21  * jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/Base64.java
22  * Revision 1.8 2002/01/05 11:15:59
23  *
24  * Eliminates dependency on sun.misc.Base64Encoding,
25  * which isn't appreciated by the J2EE security manager.
26  * (it's an access exception to load sun.misc.* classes
27  * in application code).
28  *
29  * <p>Base64 encoder and decoder.</p>
30  * <p>
31  * This class provides encoding/decoding methods for
32  * the Base64 encoding as defined by RFC 2045,
33  * N. Freed and N. Borenstein.
34  * RFC 2045: Multipurpose Internet Mail Extensions (MIME)
35  * Part One: Format of Internet Message Bodies. Reference
36  * 1996. Available at: http://www.ietf.org/rfc/rfc2045.txt
37  * </p>
38  * @author Jeffrey Rodriguez
39  */

40 final class Base64 {
41     private static final int BASELENGTH = 255;
42     private static final int LOOKUPLENGTH = 64;
43     private static final int TWENTYFOURBITGROUP = 24;
44     private static final int EIGHTBIT = 8;
45     private static final int SIXTEENBIT = 16;
46     private static final int SIXBIT = 6;
47     private static final int FOURBYTE = 4;
48     private static final int SIGN = -128;
49     private static final byte PAD = ( byte ) '=';
50     private static byte [] base64Alphabet = new byte[BASELENGTH];
51     private static byte [] lookUpBase64Alphabet = new byte[LOOKUPLENGTH];
52
53     static {
54
55         for (int i = 0; i<BASELENGTH; i++ ) {
56             base64Alphabet[i] = -1;
57         }
58         for ( int i = 'Z'; i >= 'A'; i-- ) {
59             base64Alphabet[i] = (byte) (i-'A');
60         }
61         for ( int i = 'z'; i>= 'a'; i--) {
62             base64Alphabet[i] = (byte) ( i-'a' + 26);
63         }
64
65         for ( int i = '9'; i >= '0'; i--) {
66             base64Alphabet[i] = (byte) (i-'0' + 52);
67         }
68
69         base64Alphabet['+'] = 62;
70         base64Alphabet['/'] = 63;
71
72         for (int i = 0; i<=25; i++ ) {
73             lookUpBase64Alphabet[i] = (byte) ('A'+i );
74         }
75
76         for (int i = 26, j = 0; i<=51; i++, j++ ) {
77             lookUpBase64Alphabet[i] = (byte) ('a'+ j );
78         }
79
80         for (int i = 52, j = 0; i<=61; i++, j++ ) {
81             lookUpBase64Alphabet[i] = (byte) ('0' + j );
82         }
83         lookUpBase64Alphabet[62] = (byte) '+';
84         lookUpBase64Alphabet[63] = (byte) '/';
85
86     }
87
88     static boolean isBase64( String JavaDoc isValidString ){
89         return( isArrayByteBase64( isValidString.getBytes()));
90     }
91
92
93     static boolean isBase64( byte octect ) {
94         // Should we ignore white space?
95
return(octect == PAD || base64Alphabet[octect] != -1 );
96     }
97
98
99     static boolean isArrayByteBase64( byte[] arrayOctect ) {
100         int length = arrayOctect.length;
101         if ( length == 0 ) {
102             return true;
103         }
104         for ( int i=0; i < length; i++ ) {
105             if ( Base64.isBase64( arrayOctect[i] ) == false) {
106                 return false;
107             }
108         }
109         return true;
110     }
111
112     /**
113      * Encodes hex octects into Base64
114      *
115      * @param binaryData Array containing binaryData
116      * @return Base64-encoded array
117      */

118     static byte[] encode( byte[] binaryData ) {
119
120         int lengthDataBits = binaryData.length*EIGHTBIT;
121         int fewerThan24bits = lengthDataBits%TWENTYFOURBITGROUP;
122         int numberTriplets = lengthDataBits/TWENTYFOURBITGROUP;
123         byte encodedData[] = null;
124
125
126         if ( fewerThan24bits != 0 ) {
127             //data not divisible by 24 bit
128
encodedData = new byte[ (numberTriplets + 1 )*4 ];
129         }
130         else {
131             // 16 or 8 bit
132
encodedData = new byte[ numberTriplets*4 ];
133         }
134
135         byte k=0, l=0, b1=0,b2=0,b3=0;
136
137         int encodedIndex = 0;
138         int dataIndex = 0;
139         int i = 0;
140         for ( i = 0; i<numberTriplets; i++ ) {
141
142             dataIndex = i*3;
143             b1 = binaryData[dataIndex];
144             b2 = binaryData[dataIndex + 1];
145             b3 = binaryData[dataIndex + 2];
146
147             l = (byte)(b2 & 0x0f);
148             k = (byte)(b1 & 0x03);
149
150             encodedIndex = i*4;
151             byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0);
152
153             byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0);
154             byte val3 = ((b3 & SIGN)==0)?(byte)(b3>>6):(byte)((b3)>>6^0xfc);
155
156             encodedData[encodedIndex] = lookUpBase64Alphabet[ val1 ];
157             encodedData[encodedIndex+1] = lookUpBase64Alphabet[ val2 | ( k<<4 )];
158             encodedData[encodedIndex+2] = lookUpBase64Alphabet[ (l <<2 ) | val3 ];
159             encodedData[encodedIndex+3] = lookUpBase64Alphabet[ b3 & 0x3f ];
160         }
161
162         // form integral number of 6-bit groups
163
dataIndex = i*3;
164         encodedIndex = i*4;
165         if (fewerThan24bits == EIGHTBIT ) {
166             b1 = binaryData[dataIndex];
167             k = (byte) ( b1 &0x03 );
168             byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0);
169             encodedData[encodedIndex] = lookUpBase64Alphabet[ val1 ];
170             encodedData[encodedIndex + 1] = lookUpBase64Alphabet[ k<<4 ];
171             encodedData[encodedIndex + 2] = PAD;
172             encodedData[encodedIndex + 3] = PAD;
173         } else if ( fewerThan24bits == SIXTEENBIT ) {
174             b1 = binaryData[dataIndex];
175             b2 = binaryData[dataIndex +1 ];
176             l = ( byte ) ( b2 &0x0f );
177             k = ( byte ) ( b1 &0x03 );
178
179             byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0);
180             byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0);
181
182             encodedData[encodedIndex] = lookUpBase64Alphabet[ val1 ];
183             encodedData[encodedIndex + 1] = lookUpBase64Alphabet[ val2 | ( k<<4 )];
184             encodedData[encodedIndex + 2] = lookUpBase64Alphabet[ l<<2 ];
185             encodedData[encodedIndex + 3] = PAD;
186         }
187         return encodedData;
188     }
189
190
191     /**
192      * Decodes Base64 data into octects
193      *
194      * @param base64Data Byte array containing Base64 data
195      * @return Array containing decoded data.
196      */

197     static byte[] decode( byte[] base64Data ) {
198         // Should we throw away anything not in base64Data ?
199

200         // handle the edge case, so we don't have to worry about it later
201
if(base64Data.length == 0) { return new byte[0]; }
202
203         int numberQuadruple = base64Data.length/FOURBYTE;
204         byte decodedData[] = null;
205         byte b1=0,b2=0,b3=0, b4=0, marker0=0, marker1=0;
206
207         int encodedIndex = 0;
208         int dataIndex = 0;
209         {
210             // this block sizes the output array properly - rlw
211
int lastData = base64Data.length;
212             // ignore the '=' padding
213
while(base64Data[lastData-1] == PAD) {
214                 if(--lastData == 0) { return new byte[0]; }
215             }
216             decodedData = new byte[ lastData - numberQuadruple ];
217         }
218
219         for (int i = 0; i<numberQuadruple; i++ ) {
220             dataIndex = i*4;
221             marker0 = base64Data[dataIndex +2];
222             marker1 = base64Data[dataIndex +3];
223
224             b1 = base64Alphabet[base64Data[dataIndex]];
225             b2 = base64Alphabet[base64Data[dataIndex +1]];
226
227             if ( marker0 != PAD && marker1 != PAD ) { //No PAD e.g 3cQl
228
b3 = base64Alphabet[ marker0 ];
229                 b4 = base64Alphabet[ marker1 ];
230
231                 decodedData[encodedIndex] = (byte)( b1 <<2 | b2>>4 ) ;
232                 decodedData[encodedIndex+1] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) );
233                 decodedData[encodedIndex+2] = (byte)( b3<<6 | b4 );
234             } else if ( marker0 == PAD ) { //Two PAD e.g. 3c[Pad][Pad]
235
decodedData[encodedIndex] = (byte)( b1 <<2 | b2>>4 ) ;
236             } else if ( marker1 == PAD ) { //One PAD e.g. 3cQ[Pad]
237
b3 = base64Alphabet[ marker0 ];
238
239                 decodedData[encodedIndex] = (byte)( b1 <<2 | b2>>4 );
240                 decodedData[encodedIndex+1] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) );
241             }
242             encodedIndex += 3;
243         }
244         return decodedData;
245     }
246
247 }
248
Popular Tags