1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 package JADE_SL;
46
47
48
49 /***
50
51 * Provides encoding of raw bytes to base64-encoded characters, and
52
53 * decoding of base64 characters to raw bytes.
54
55 *
56
57 * @author Kevin Kelley (kelley@iguana.ruralnet.net)
58
59 * @version 1.0
60
61 * @date 06 August 1998
62
63 */
64
65 public class Base64 {
66
67
68
69 /***
70
71 * returns an array of base64-encoded characters to represent the
72
73 * passed data array.
74
75 *
76
77 * @param data the array of bytes to encode
78
79 * @return base64-coded character array.
80
81 */
82
83 static public char[] encode(byte[] data)
84
85 {
86
87 char[] out = new char[((data.length + 2) / 3) * 4];
88
89
90
91
92
93
94
95
96
97
98
99 for (int i=0, index=0; i<data.length; i+=3, index+=4) {
100
101 boolean quad = false;
102
103 boolean trip = false;
104
105
106
107 int val = (0xFF & (int) data[i]);
108
109 val <<= 8;
110
111 if ((i+1) < data.length) {
112
113 val |= (0xFF & (int) data[i+1]);
114
115 trip = true;
116
117 }
118
119 val <<= 8;
120
121 if ((i+2) < data.length) {
122
123 val |= (0xFF & (int) data[i+2]);
124
125 quad = true;
126
127 }
128
129 out[index+3] = alphabet[(quad? (val & 0x3F): 64)];
130
131 val >>= 6;
132
133 out[index+2] = alphabet[(trip? (val & 0x3F): 64)];
134
135 val >>= 6;
136
137 out[index+1] = alphabet[val & 0x3F];
138
139 val >>= 6;
140
141 out[index+0] = alphabet[val & 0x3F];
142
143 }
144
145 return out;
146
147 }
148
149
150
151 /***
152
153 * Returns an array of bytes which were encoded in the passed
154
155 * character array.
156
157 *
158
159 * @param data the array of base64-encoded characters
160
161 * @return decoded data array
162
163 */
164
165 static public byte[] decode(char[] data)
166
167 {
168
169 int len = ((data.length + 3) / 4) * 3;
170
171 if (data.length>0 && data[data.length-1] == '=') --len;
172
173 if (data.length>1 && data[data.length-2] == '=') --len;
174
175 byte[] out = new byte[len];
176
177
178
179 int shift = 0;
180
181 int accum = 0;
182
183 int index = 0;
184
185
186
187 for (int ix=0; ix<data.length; ix++)
188
189 {
190
191 int value = codes[ data[ix] & 0xFF ];
192
193 if ( value >= 0 ) {
194
195 accum <<= 6;
196
197 shift += 6;
198
199 accum |= value;
200
201 if ( shift >= 8 ) {
202
203 shift -= 8;
204
205 out[index++] =
206
207 (byte) ((accum >> shift) & 0xff);
208
209 } } }
210
211 if (index != out.length)
212
213 throw new Error("miscalculated data length!");
214
215
216
217 return out;
218
219 }
220
221
222
223
224
225
226
227
228
229 static private char[] alphabet =
230
231 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
232
233 .toCharArray();
234
235
236
237
238
239
240
241
242
243 static private byte[] codes = new byte[256];
244
245 static {
246
247 for (int i=0; i<256; i++) codes[i] = -1;
248
249 for (int i = 'A'; i <= 'Z'; i++) codes[i] = (byte)( i - 'A');
250
251 for (int i = 'a'; i <= 'z'; i++) codes[i] = (byte)(26 + i - 'a');
252
253 for (int i = '0'; i <= '9'; i++) codes[i] = (byte)(52 + i - '0');
254
255 codes['+'] = 62;
256
257 codes['/'] = 63;
258
259 }
260
261
262
263 }
264