KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tomcat > util > buf > Base64


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

17
18
19 package org.apache.tomcat.util.buf;
20
21
22 /**
23  * This class provides encode/decode for RFC 2045 Base64 as
24  * defined by RFC 2045, N. Freed and N. Borenstein.
25  * RFC 2045: Multipurpose Internet Mail Extensions (MIME)
26  * Part One: Format of Internet Message Bodies. Reference
27  * 1996 Available at: http://www.ietf.org/rfc/rfc2045.txt
28  * This class is used by XML Schema binary format validation
29  *
30  * @author Jeffrey Rodriguez
31  * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
32  */

33
34 public final class Base64 {
35
36
37     private static org.apache.commons.logging.Log log=
38         org.apache.commons.logging.LogFactory.getLog( Base64.class );
39     
40     static private final int BASELENGTH = 255;
41     static private final int LOOKUPLENGTH = 63;
42     static private final int TWENTYFOURBITGROUP = 24;
43     static private final int EIGHTBIT = 8;
44     static private final int SIXTEENBIT = 16;
45     static private final int SIXBIT = 6;
46     static private final int FOURBYTE = 4;
47
48
49     static private final byte PAD = ( byte ) '=';
50     static private byte [] base64Alphabet = new byte[BASELENGTH];
51     static private 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         for (int i = 26, j = 0; i<=51; i++, j++ )
76             lookUpBase64Alphabet[i] = (byte) ('a'+ j );
77
78         for (int i = 52, j = 0; i<=61; i++, j++ )
79             lookUpBase64Alphabet[i] = (byte) ('0' + j );
80
81     }
82
83
84     static boolean isBase64( byte octect ) {
85         //shall we ignore white space? JEFF??
86
return(octect == PAD || base64Alphabet[octect] != -1 );
87     }
88
89
90     static boolean isArrayByteBase64( byte[] arrayOctect ) {
91         int length = arrayOctect.length;
92         if ( length == 0 )
93             return false;
94         for ( int i=0; i < length; i++ ) {
95             if ( Base64.isBase64( arrayOctect[i] ) == false)
96                 return false;
97         }
98         return true;
99     }
100
101     /**
102      * Encodes hex octects into Base64
103      *
104      * @param binaryData Array containing binaryData
105      * @return Encoded Base64 array
106      */

107     public static byte[] encode( byte[] binaryData ) {
108         int lengthDataBits = binaryData.length*EIGHTBIT;
109         int fewerThan24bits = lengthDataBits%TWENTYFOURBITGROUP;
110         int numberTriplets = lengthDataBits/TWENTYFOURBITGROUP;
111         byte encodedData[] = null;
112
113
114         if ( fewerThan24bits != 0 ) //data not divisible by 24 bit
115
encodedData = new byte[ (numberTriplets + 1 )*4 ];
116         else // 16 or 8 bit
117
encodedData = new byte[ numberTriplets*4 ];
118
119         byte k=0, l=0, b1=0,b2=0,b3=0;
120
121         int encodedIndex = 0;
122         int dataIndex = 0;
123         int i = 0;
124         for ( i = 0; i<numberTriplets; i++ ) {
125
126             dataIndex = i*3;
127             b1 = binaryData[dataIndex];
128             b2 = binaryData[dataIndex + 1];
129             b3 = binaryData[dataIndex + 2];
130
131             l = (byte)(b2 & 0x0f);
132             k = (byte)(b1 & 0x03);
133
134             encodedIndex = i*4;
135             encodedData[encodedIndex] = lookUpBase64Alphabet[ b1 >>2 ];
136             encodedData[encodedIndex+1] = lookUpBase64Alphabet[(b2 >>4 ) |
137 ( k<<4 )];
138             encodedData[encodedIndex+2] = lookUpBase64Alphabet[ (l <<2 ) |
139 ( b3>>6)];
140             encodedData[encodedIndex+3] = lookUpBase64Alphabet[ b3 & 0x3f ];
141         }
142
143         // form integral number of 6-bit groups
144
dataIndex = i*3;
145         encodedIndex = i*4;
146         if (fewerThan24bits == EIGHTBIT ) {
147             b1 = binaryData[dataIndex];
148             k = (byte) ( b1 &0x03 );
149             encodedData[encodedIndex] = lookUpBase64Alphabet[ b1 >>2 ];
150             encodedData[encodedIndex + 1] = lookUpBase64Alphabet[ k<<4 ];
151             encodedData[encodedIndex + 2] = PAD;
152             encodedData[encodedIndex + 3] = PAD;
153         } else if ( fewerThan24bits == SIXTEENBIT ) {
154
155             b1 = binaryData[dataIndex];
156             b2 = binaryData[dataIndex +1 ];
157             l = ( byte ) ( b2 &0x0f );
158             k = ( byte ) ( b1 &0x03 );
159             encodedData[encodedIndex] = lookUpBase64Alphabet[ b1 >>2 ];
160             encodedData[encodedIndex + 1] = lookUpBase64Alphabet[ (b2 >>4 )
161 | ( k<<4 )];
162             encodedData[encodedIndex + 2] = lookUpBase64Alphabet[ l<<2 ];
163             encodedData[encodedIndex + 3] = PAD;
164         }
165         return encodedData;
166     }
167
168
169     /**
170      * Decodes Base64 data into octects
171      *
172      * @param base64Data Byte array containing Base64 data
173      * @return Array containind decoded data.
174      */

175     public byte[] decode( byte[] base64Data ) {
176         int numberQuadruple = base64Data.length/FOURBYTE;
177         byte decodedData[] = null;
178         byte b1=0,b2=0,b3=0, b4=0, marker0=0, marker1=0;
179
180         // Throw away anything not in base64Data
181
// Adjust size
182

183         int encodedIndex = 0;
184         int dataIndex = 0;
185         decodedData = new byte[ numberQuadruple*3 + 1 ];
186
187         for (int i = 0; i<numberQuadruple; i++ ) {
188             dataIndex = i*4;
189             marker0 = base64Data[dataIndex +2];
190             marker1 = base64Data[dataIndex +3];
191
192             b1 = base64Alphabet[base64Data[dataIndex]];
193             b2 = base64Alphabet[base64Data[dataIndex +1]];
194
195             if ( marker0 != PAD && marker1 != PAD ) { //No PAD e.g 3cQl
196
b3 = base64Alphabet[ marker0 ];
197                 b4 = base64Alphabet[ marker1 ];
198
199                 decodedData[encodedIndex] = (byte)( b1 <<2 | b2>>4 ) ;
200                 decodedData[encodedIndex+1] = (byte)(((b2 & 0xf)<<4 ) |(
201 (b3>>2) & 0xf) );
202                 decodedData[encodedIndex+2] = (byte)( b3<<6 | b4 );
203             } else if ( marker0 == PAD ) { //Two PAD e.g. 3c[Pad][Pad]
204
decodedData[encodedIndex] = (byte)( b1 <<2 | b2>>4 ) ;
205                 decodedData[encodedIndex+1] = (byte)((b2 & 0xf)<<4 );
206                 decodedData[encodedIndex+2] = (byte) 0;
207             } else if ( marker1 == PAD ) { //One PAD e.g. 3cQ[Pad]
208
b3 = base64Alphabet[ marker0 ];
209
210                 decodedData[encodedIndex] = (byte)( b1 <<2 | b2>>4 );
211                 decodedData[encodedIndex+1] = (byte)(((b2 & 0xf)<<4 ) |(
212 (b3>>2) & 0xf) );
213                 decodedData[encodedIndex+2] = (byte)( b3<<6);
214             }
215             encodedIndex += 3;
216         }
217         return decodedData;
218
219     }
220
221     static final int base64[]= {
222     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
223         64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
224         64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
225         52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
226         64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
227         15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
228         64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
229         41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
230         64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
231         64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
232         64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
233         64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
234         64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
235         64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
236         64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
237         64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
238     };
239
240     public static String JavaDoc base64Decode( String JavaDoc orig ) {
241     char chars[]=orig.toCharArray();
242     StringBuffer JavaDoc sb=new StringBuffer JavaDoc();
243     int i=0;
244
245     int shift = 0; // # of excess bits stored in accum
246
int acc = 0;
247     
248     for (i=0; i<chars.length; i++) {
249         int v = base64[ chars[i] & 0xFF ];
250         
251         if ( v >= 64 ) {
252         if( chars[i] != '=' )
253                     if (log.isDebugEnabled())
254                         log.debug("Wrong char in base64: " + chars[i]);
255         } else {
256         acc= ( acc << 6 ) | v;
257         shift += 6;
258         if ( shift >= 8 ) {
259             shift -= 8;
260             sb.append( (char) ((acc >> shift) & 0xff));
261         }
262         }
263     }
264     return sb.toString();
265     }
266
267
268 }
269
270
Popular Tags