1
16
17
20
21 package org.apache.wsrp4j.producer.util;
22
23
77
78 import java.io.IOException;
79 import java.io.OutputStream;
80 import java.io.Writer;
81
82 import org.apache.axis.utils.Messages;
83
84
91 public class Base64 {
92 private static final char[] S_BASE64CHAR = { 'A', 'B', 'C', 'D', 'E', 'F',
93 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
94 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
95 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
96 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',
97 '6', '7', '8', '9', '-', '_' };
98
99 private static final char S_BASE64PAD = '*';
100
101 private static final byte[] S_DECODETABLE = new byte[128];
102 static {
103 for (int i = 0; i < S_DECODETABLE.length; i++)
104 S_DECODETABLE[i] = Byte.MAX_VALUE; for (int i = 0; i < S_BASE64CHAR.length; i++)
106 S_DECODETABLE[S_BASE64CHAR[i]] = (byte) i;
108 }
109
110 private static int decode0(char[] ibuf, byte[] obuf, int wp) {
111 int outlen = 3;
112 if (ibuf[3] == S_BASE64PAD)
113 outlen = 2;
114 if (ibuf[2] == S_BASE64PAD)
115 outlen = 1;
116 int b0 = S_DECODETABLE[ibuf[0]];
117 int b1 = S_DECODETABLE[ibuf[1]];
118 int b2 = S_DECODETABLE[ibuf[2]];
119 int b3 = S_DECODETABLE[ibuf[3]];
120 switch (outlen) {
121 case 1:
122 obuf[wp] = (byte) (b0 << 2 & 0xfc | b1 >> 4 & 0x3);
123 return 1;
124 case 2:
125 obuf[wp++] = (byte) (b0 << 2 & 0xfc | b1 >> 4 & 0x3);
126 obuf[wp] = (byte) (b1 << 4 & 0xf0 | b2 >> 2 & 0xf);
127 return 2;
128 case 3:
129 obuf[wp++] = (byte) (b0 << 2 & 0xfc | b1 >> 4 & 0x3);
130 obuf[wp++] = (byte) (b1 << 4 & 0xf0 | b2 >> 2 & 0xf);
131 obuf[wp] = (byte) (b2 << 6 & 0xc0 | b3 & 0x3f);
132 return 3;
133 default:
134 throw new RuntimeException(Messages.getMessage("internalError00"));
135 }
136 }
137
138
141 public static byte[] decode(char[] data, int off, int len) {
142 char[] ibuf = new char[4];
143 int ibufcount = 0;
144 byte[] obuf = new byte[len / 4 * 3 + 3];
145 int obufcount = 0;
146 for (int i = off; i < off + len; i++) {
147 char ch = data[i];
148 if (ch == S_BASE64PAD || ch < S_DECODETABLE.length
149 && S_DECODETABLE[ch] != Byte.MAX_VALUE) {
150 ibuf[ibufcount++] = ch;
151 if (ibufcount == ibuf.length) {
152 ibufcount = 0;
153 obufcount += decode0(ibuf, obuf, obufcount);
154 }
155 }
156 }
157 if (obufcount == obuf.length)
158 return obuf;
159 byte[] ret = new byte[obufcount];
160 System.arraycopy(obuf, 0, ret, 0, obufcount);
161 return ret;
162 }
163
164
167 public static byte[] decode(String data) {
168 char[] ibuf = new char[4];
169 int ibufcount = 0;
170 byte[] obuf = new byte[data.length() / 4 * 3 + 3];
171 int obufcount = 0;
172 for (int i = 0; i < data.length(); i++) {
173 char ch = data.charAt(i);
174 if (ch == S_BASE64PAD || ch < S_DECODETABLE.length
175 && S_DECODETABLE[ch] != Byte.MAX_VALUE) {
176 ibuf[ibufcount++] = ch;
177 if (ibufcount == ibuf.length) {
178 ibufcount = 0;
179 obufcount += decode0(ibuf, obuf, obufcount);
180 }
181 }
182 }
183 if (obufcount == obuf.length)
184 return obuf;
185 byte[] ret = new byte[obufcount];
186 System.arraycopy(obuf, 0, ret, 0, obufcount);
187 return ret;
188 }
189
190
193 public static void decode(char[] data, int off, int len,
194 OutputStream ostream) throws IOException {
195 char[] ibuf = new char[4];
196 int ibufcount = 0;
197 byte[] obuf = new byte[3];
198 for (int i = off; i < off + len; i++) {
199 char ch = data[i];
200 if (ch == S_BASE64PAD || ch < S_DECODETABLE.length
201 && S_DECODETABLE[ch] != Byte.MAX_VALUE) {
202 ibuf[ibufcount++] = ch;
203 if (ibufcount == ibuf.length) {
204 ibufcount = 0;
205 int obufcount = decode0(ibuf, obuf, 0);
206 ostream.write(obuf, 0, obufcount);
207 }
208 }
209 }
210 }
211
212
215 public static void decode(String data, OutputStream ostream)
216 throws IOException {
217 char[] ibuf = new char[4];
218 int ibufcount = 0;
219 byte[] obuf = new byte[3];
220 for (int i = 0; i < data.length(); i++) {
221 char ch = data.charAt(i);
222 if (ch == S_BASE64PAD || ch < S_DECODETABLE.length
223 && S_DECODETABLE[ch] != Byte.MAX_VALUE) {
224 ibuf[ibufcount++] = ch;
225 if (ibufcount == ibuf.length) {
226 ibufcount = 0;
227 int obufcount = decode0(ibuf, obuf, 0);
228 ostream.write(obuf, 0, obufcount);
229 }
230 }
231 }
232 }
233
234
237 public static String encode(byte[] data) {
238 return encode(data, 0, data.length);
239 }
240
241
244 public static String encode(byte[] data, int off, int len) {
245 if (len <= 0)
246 return "";
247 char[] out = new char[len / 3 * 4 + 4];
248 int rindex = off;
249 int windex = 0;
250 int rest = len - off;
251 while (rest >= 3) {
252 int i = ((data[rindex] & 0xff) << 16)
253 + ((data[rindex + 1] & 0xff) << 8)
254 + (data[rindex + 2] & 0xff);
255 out[windex++] = S_BASE64CHAR[i >> 18];
256 out[windex++] = S_BASE64CHAR[(i >> 12) & 0x3f];
257 out[windex++] = S_BASE64CHAR[(i >> 6) & 0x3f];
258 out[windex++] = S_BASE64CHAR[i & 0x3f];
259 rindex += 3;
260 rest -= 3;
261 }
262 if (rest == 1) {
263 int i = data[rindex] & 0xff;
264 out[windex++] = S_BASE64CHAR[i >> 2];
265 out[windex++] = S_BASE64CHAR[(i << 4) & 0x3f];
266 out[windex++] = S_BASE64PAD;
267 out[windex++] = S_BASE64PAD;
268 }
269 else if (rest == 2) {
270 int i = ((data[rindex] & 0xff) << 8) + (data[rindex + 1] & 0xff);
271 out[windex++] = S_BASE64CHAR[i >> 10];
272 out[windex++] = S_BASE64CHAR[(i >> 4) & 0x3f];
273 out[windex++] = S_BASE64CHAR[(i << 2) & 0x3f];
274 out[windex++] = S_BASE64PAD;
275 }
276 return new String(out, 0, windex);
277 }
278
279
282 public static void encode(byte[] data, int off, int len,
283 OutputStream ostream) throws IOException {
284 if (len <= 0)
285 return;
286 byte[] out = new byte[4];
287 int rindex = off;
288 int rest = len - off;
289 while (rest >= 3) {
290 int i = ((data[rindex] & 0xff) << 16)
291 + ((data[rindex + 1] & 0xff) << 8)
292 + (data[rindex + 2] & 0xff);
293 out[0] = (byte) S_BASE64CHAR[i >> 18];
294 out[1] = (byte) S_BASE64CHAR[(i >> 12) & 0x3f];
295 out[2] = (byte) S_BASE64CHAR[(i >> 6) & 0x3f];
296 out[3] = (byte) S_BASE64CHAR[i & 0x3f];
297 ostream.write(out, 0, 4);
298 rindex += 3;
299 rest -= 3;
300 }
301 if (rest == 1) {
302 int i = data[rindex] & 0xff;
303 out[0] = (byte) S_BASE64CHAR[i >> 2];
304 out[1] = (byte) S_BASE64CHAR[(i << 4) & 0x3f];
305 out[2] = (byte) S_BASE64PAD;
306 out[3] = (byte) S_BASE64PAD;
307 ostream.write(out, 0, 4);
308 }
309 else if (rest == 2) {
310 int i = ((data[rindex] & 0xff) << 8) + (data[rindex + 1] & 0xff);
311 out[0] = (byte) S_BASE64CHAR[i >> 10];
312 out[1] = (byte) S_BASE64CHAR[(i >> 4) & 0x3f];
313 out[2] = (byte) S_BASE64CHAR[(i << 2) & 0x3f];
314 out[3] = (byte) S_BASE64PAD;
315 ostream.write(out, 0, 4);
316 }
317 }
318
319
322 public static void encode(byte[] data, int off, int len, Writer writer)
323 throws IOException {
324 if (len <= 0)
325 return;
326 char[] out = new char[4];
327 int rindex = off;
328 int rest = len - off;
329 int output = 0;
330 while (rest >= 3) {
331 int i = ((data[rindex] & 0xff) << 16)
332 + ((data[rindex + 1] & 0xff) << 8)
333 + (data[rindex + 2] & 0xff);
334 out[0] = S_BASE64CHAR[i >> 18];
335 out[1] = S_BASE64CHAR[(i >> 12) & 0x3f];
336 out[2] = S_BASE64CHAR[(i >> 6) & 0x3f];
337 out[3] = S_BASE64CHAR[i & 0x3f];
338 writer.write(out, 0, 4);
339 rindex += 3;
340 rest -= 3;
341 output += 4;
342 if (output % 76 == 0)
343 writer.write("\n");
344 }
345 if (rest == 1) {
346 int i = data[rindex] & 0xff;
347 out[0] = S_BASE64CHAR[i >> 2];
348 out[1] = S_BASE64CHAR[(i << 4) & 0x3f];
349 out[2] = S_BASE64PAD;
350 out[3] = S_BASE64PAD;
351 writer.write(out, 0, 4);
352 }
353 else if (rest == 2) {
354 int i = ((data[rindex] & 0xff) << 8) + (data[rindex + 1] & 0xff);
355 out[0] = S_BASE64CHAR[i >> 10];
356 out[1] = S_BASE64CHAR[(i >> 4) & 0x3f];
357 out[2] = S_BASE64CHAR[(i << 2) & 0x3f];
358 out[3] = S_BASE64PAD;
359 writer.write(out, 0, 4);
360 }
361 }
362 }