KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > tomcat5 > Base64


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.tomcat5;
21
22 /**
23  * This class provides encode/decode for RFC 2045 Base64 as defined by
24  * RFC 2045, N. Freed and N. Borenstein. <a
25  * HREF="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>:
26  * Multipurpose Internet Mail Extensions (MIME) Part One: Format of
27  * Internet Message Bodies. Reference 1996
28  */

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

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

198     public static byte[] decode( byte[] 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         // Throw away anything not in base64Data
208

209         int encodedIndex = 0;
210         int dataIndex = 0;
211         {
212             // this sizes the output array properly - rlw
213
int lastData = base64Data.length;
214             // ignore the '=' padding
215
while (base64Data[lastData-1] == PAD)
216             {
217                 if (--lastData == 0)
218                 {
219                     return new byte[0];
220                 }
221             }
222             decodedData = new byte[ lastData - numberQuadruple ];
223         }
224
225         for (int i = 0; i < numberQuadruple; i++)
226         {
227             dataIndex = i * 4;
228             marker0 = base64Data[dataIndex + 2];
229             marker1 = base64Data[dataIndex + 3];
230
231             b1 = base64Alphabet[base64Data[dataIndex]];
232             b2 = base64Alphabet[base64Data[dataIndex +1]];
233
234             if (marker0 != PAD && marker1 != PAD)
235             {
236                 //No PAD e.g 3cQl
237
b3 = base64Alphabet[ marker0 ];
238                 b4 = base64Alphabet[ marker1 ];
239
240                 decodedData[encodedIndex] = (byte)( b1 <<2 | b2>>4 ) ;
241                 decodedData[encodedIndex + 1] =
242                     (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) );
243                 decodedData[encodedIndex + 2] = (byte)( b3<<6 | b4 );
244             }
245             else if (marker0 == PAD)
246             {
247                 //Two PAD e.g. 3c[Pad][Pad]
248
decodedData[encodedIndex] = (byte)( b1 <<2 | b2>>4 ) ;
249             }
250             else if (marker1 == PAD)
251             {
252                 //One PAD e.g. 3cQ[Pad]
253
b3 = base64Alphabet[ marker0 ];
254
255                 decodedData[encodedIndex] = (byte)( b1 <<2 | b2>>4 );
256                 decodedData[encodedIndex + 1] =
257                     (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) );
258             }
259             encodedIndex += 3;
260         }
261         return decodedData;
262     }
263
264
265 }
266
Popular Tags