KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jas > Base64


1 // *** WARNING ***
2
// This Soot file has been copied to jas, as it is required for
3
// jas and jasmin compilation. In the unlikely event that any changes are
4
// made to this file, they should be reflected in the Soot
5
// distribution.
6
// - Patrick Lam, 01/25/2001
7
// *** END-WARNING ***
8

9
10 //////////////////////license & copyright header/////////////////////////
11
// //
12
// Base64 - encode/decode data using the Base64 encoding scheme //
13
// //
14
// Copyright (c) 1998 by Kevin Kelley //
15
// //
16
// This library is free software; you can redistribute it and/or //
17
// modify it under the terms of the GNU Lesser General Public //
18
// License as published by the Free Software Foundation; either //
19
// version 2.1 of the License, or (at your option) any later version. //
20
// //
21
// This library is distributed in the hope that it will be useful, //
22
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
23
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
24
// GNU Lesser General Public License for more details. //
25
// //
26
// You should have received a copy of the GNU Lesser General Public //
27
// License along with this library; if not, write to the Free Software //
28
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA //
29
// 02111-1307, USA, or contact the author: //
30
// //
31
// Kevin Kelley <kelley@ruralnet.net> - 30718 Rd. 28, La Junta, CO, //
32
// 81050 USA. //
33
// //
34
////////////////////end license & copyright header///////////////////////
35

36 package jas;
37
38 /**
39 * Provides encoding of raw bytes to base64-encoded characters, and
40 * decoding of base64 characters to raw bytes.
41 *
42 * @author Kevin Kelley (kelley@ruralnet.net)
43 * @version 1.3
44 * @date 06 August 1998
45 * @modified 14 February 2000
46 * @modified 22 September 2000
47 */

48 public class Base64 {
49
50 /**
51 * returns an array of base64-encoded characters to represent the
52 * passed data array.
53 *
54 * @param data the array of bytes to encode
55 * @return base64-coded character array.
56 */

57 static public char[] encode(byte[] data)
58 {
59     char[] out = new char[((data.length + 2) / 3) * 4];
60
61     //
62
// 3 bytes encode to 4 chars. Output is always an even
63
// multiple of 4 characters.
64
//
65
for (int i=0, index=0; i<data.length; i+=3, index+=4) {
66         boolean quad = false;
67         boolean trip = false;
68
69         int val = (0xFF & (int) data[i]);
70         val <<= 8;
71         if ((i+1) < data.length) {
72             val |= (0xFF & (int) data[i+1]);
73             trip = true;
74         }
75         val <<= 8;
76         if ((i+2) < data.length) {
77             val |= (0xFF & (int) data[i+2]);
78             quad = true;
79         }
80         out[index+3] = alphabet[(quad? (val & 0x3F): 64)];
81         val >>= 6;
82         out[index+2] = alphabet[(trip? (val & 0x3F): 64)];
83         val >>= 6;
84         out[index+1] = alphabet[val & 0x3F];
85         val >>= 6;
86         out[index+0] = alphabet[val & 0x3F];
87     }
88     return out;
89 }
90
91   /**
92    * Decodes a BASE-64 encoded stream to recover the original
93    * data. White space before and after will be trimmed away,
94    * but no other manipulation of the input will be performed.
95    *
96    * As of version 1.2 this method will properly handle input
97    * containing junk characters (newlines and the like) rather
98    * than throwing an error. It does this by pre-parsing the
99    * input and generating from that a count of VALID input
100    * characters.
101    **/

102 static public byte[] decode(char[] data)
103 {
104     // as our input could contain non-BASE64 data (newlines,
105
// whitespace of any sort, whatever) we must first adjust
106
// our count of USABLE data so that...
107
// (a) we don't misallocate the output array, and
108
// (b) think that we miscalculated our data length
109
// just because of extraneous throw-away junk
110

111     int tempLen = data.length;
112     for( int ix=0; ix<data.length; ix++ )
113     {
114         if( (data[ix] > 255) || codes[ data[ix] ] < 0 )
115             --tempLen; // ignore non-valid chars and padding
116
}
117     // calculate required length:
118
// -- 3 bytes for every 4 valid base64 chars
119
// -- plus 2 bytes if there are 3 extra base64 chars,
120
// or plus 1 byte if there are 2 extra.
121

122     int len = (tempLen / 4) * 3;
123     if ((tempLen % 4) == 3) len += 2;
124     if ((tempLen % 4) == 2) len += 1;
125
126     byte[] out = new byte[len];
127
128
129
130     int shift = 0; // # of excess bits stored in accum
131
int accum = 0; // excess bits
132
int index = 0;
133
134     // we now go through the entire array (NOT using the 'tempLen' value)
135
for (int ix=0; ix<data.length; ix++)
136     {
137         int value = (data[ix]>255)? -1: codes[ data[ix] ];
138
139         if ( value >= 0 ) // skip over non-code
140
{
141             accum <<= 6; // bits shift up by 6 each time thru
142
shift += 6; // loop, with new bits being put in
143
accum |= value; // at the bottom.
144
if ( shift >= 8 ) // whenever there are 8 or more shifted in,
145
{
146                 shift -= 8; // write them out (from the top, leaving any
147
out[index++] = // excess at the bottom for next iteration.
148
(byte) ((accum >> shift) & 0xff);
149             }
150         }
151         // we will also have skipped processing a padding null byte ('=') here;
152
// these are used ONLY for padding to an even length and do not legally
153
// occur as encoded data. for this reason we can ignore the fact that
154
// no index++ operation occurs in that special case: the out[] array is
155
// initialized to all-zero bytes to start with and that works to our
156
// advantage in this combination.
157
}
158
159     // if there is STILL something wrong we just have to throw up now!
160
if( index != out.length)
161     {
162         throw new Error JavaDoc("Miscalculated data length (wrote " + index + " instead of " + out.length + ")");
163     }
164
165     return out;
166 }
167
168
169 //
170
// code characters for values 0..63
171
//
172
static private char[] alphabet =
173     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
174         .toCharArray();
175
176 //
177
// lookup table for converting base64 characters to value in range 0..63
178
//
179
static private byte[] codes = new byte[256];
180 static {
181     for (int i=0; i<256; i++) codes[i] = -1;
182     for (int i = 'A'; i <= 'Z'; i++) codes[i] = (byte)( i - 'A');
183     for (int i = 'a'; i <= 'z'; i++) codes[i] = (byte)(26 + i - 'a');
184     for (int i = '0'; i <= '9'; i++) codes[i] = (byte)(52 + i - '0');
185     codes['+'] = 62;
186     codes['/'] = 63;
187 }
188
189 }
190
Popular Tags