1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package com.gridsystems;
19
20 import java.io.ByteArrayInputStream;
21 import java.io.ByteArrayOutputStream;
22 import java.io.FilterInputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 public class Base64Decoder extends FilterInputStream {
46
47
48 private static final char[] CHARS = {
49 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
50 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
51 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
52 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
53 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
54 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
55 '8', '9', '+', '/'
56 };
57
58
59 private static final int[] INTS = new int[128];
60 static {
61 for (int i = 0; i < 64; i++) {
62 INTS[CHARS[i]] = i;
63 }
64 }
65
66
67 private int charCount;
68
69 private int carryOver;
70
71
72
73
74
75
76
77 public Base64Decoder(InputStream in) {
78 super(in);
79 }
80
81
82
83
84
85
86
87
88
89 public int read() throws IOException {
90 try {
91
92 int x;
93 do {
94 x = in.read();
95 if (x == -1) {
96 return -1;
97 }
98 } while (Character.isWhitespace((char) x));
99 charCount++;
100
101
102 if (x == '=') {
103 return -1;
104 }
105
106
107 x = INTS[x];
108
109
110 int mode = (charCount - 1) % 4;
111
112
113 if (mode == 0) {
114 carryOver = x & 63;
115 return read();
116 } else if (mode == 1) {
117
118
119 int decoded = ((carryOver << 2) + (x >> 4)) & 255;
120 carryOver = x & 15;
121 return decoded;
122 } else if (mode == 2) {
123
124
125 int decoded = ((carryOver << 4) + (x >> 2)) & 255;
126 carryOver = x & 3;
127 return decoded;
128 } else if (mode == 3) {
129
130 int decoded = ((carryOver << 6) + x) & 255;
131 return decoded;
132 }
133 } catch (ArrayIndexOutOfBoundsException aioobe) {
134 throw new IOException("Corrupted Base64 stream");
135 }
136 return -1;
137 }
138
139
140
141
142
143
144
145
146
147
148
149
150 public int read(byte[] b, int off, int len) throws IOException {
151
152 int i;
153 for (i = 0; i < len; i++) {
154 int x = read();
155 if (x == -1 && i == 0) {
156 return -1;
157 } else if (x == -1) {
158 break;
159 }
160 b[off + i] = (byte) x;
161 }
162 return i;
163 }
164
165
166
167
168
169
170
171 public static String decode(String encoded) {
172 byte[] bytes = null;
173
174 bytes = encoded.getBytes();
175
176 Base64Decoder in = new Base64Decoder(new ByteArrayInputStream(bytes));
177
178 ByteArrayOutputStream out = new ByteArrayOutputStream((int) (bytes.length * 0.67));
179
180 try {
181 byte[] buf = new byte[4 * 1024];
182 int bytesRead;
183 while ((bytesRead = in.read(buf)) != -1) {
184 out.write(buf, 0, bytesRead);
185 }
186 out.close();
187
188 return out.toString("UTF-8");
189 } catch (IOException ignored) { return null; }
190 }
191
192
193
194
195
196
197
198 public static byte[] binaryDecode(byte[] encoded) {
199 Base64Decoder in = new Base64Decoder(new ByteArrayInputStream(encoded));
200
201 ByteArrayOutputStream out = new ByteArrayOutputStream((int) (encoded.length * 0.67));
202
203 try {
204 byte[] buf = new byte[4 * 1024];
205 int bytesRead;
206 while ((bytesRead = in.read(buf)) != -1) {
207 out.write(buf, 0, bytesRead);
208 }
209 out.close();
210
211 return out.toByteArray();
212 } catch (IOException ignored) { return new byte[0]; }
213 }
214
215 }