/
Base64.java
executable file
·155 lines (132 loc) · 3.09 KB
/
Base64.java
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package aQute.lib.base64;
import java.io.*;
/*
* Base 64 converter.
*
* TODO Implement string to byte[]
*/
public class Base64 {
byte[] data;
static final String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static byte[] values = new byte[128];
static {
for (int i = 0; i < values.length; i++) {
values[i] = -1;
}
// Create reverse index
for (int i = 0; i < alphabet.length(); i++) {
char c = alphabet.charAt(i);
values[c] = (byte) i;
}
}
public Base64(byte data[]) {
this.data = data;
}
public final static byte[] decodeBase64(String string) {
ByteArrayOutputStream bout = new ByteArrayOutputStream(string.length() * 2 / 3);
StringReader rdr = new StringReader(string.trim());
try {
decode(rdr, bout);
}
catch (Exception e) {
// cannot happen
}
return bout.toByteArray();
}
public final static void decode(Reader rdr, OutputStream out) throws Exception {
int register = 0;
int i = 0;
int pads = 0;
byte test[] = new byte[3];
int c;
while ((c = rdr.read()) >= 0) {
if (c > 0x7F)
throw new IllegalArgumentException("Invalid base64 character in " + rdr + ", character value > 128 ");
int v = 0;
if (c == '=') {
pads++;
} else {
v = values[c];
if (v < 0)
throw new IllegalArgumentException("Invalid base64 character in " + rdr + ", " + c);
}
register <<= 6;
register |= v;
test[2] = (byte) (register & 0xFF);
test[1] = (byte) ((register >> 8) & 0xFF);
test[0] = (byte) ((register >> 16) & 0xFF);
i++;
if ((i % 4) == 0) {
flush(out, register, pads);
register = 0;
pads = 0;
}
}
}
static private void flush(OutputStream out, int register, int pads) throws IOException {
switch (pads) {
case 0 :
out.write(0xFF & (register >> 16));
out.write(0xFF & (register >> 8));
out.write(0xFF & (register >> 0));
break;
case 1 :
out.write(0xFF & (register >> 16));
out.write(0xFF & (register >> 8));
break;
case 2 :
out.write(0xFF & (register >> 16));
}
}
public Base64(String s) {
data = decodeBase64(s);
}
@Override
public String toString() {
return encodeBase64(data);
}
public static String encodeBase64(byte data[]) {
StringWriter sw = new StringWriter();
ByteArrayInputStream bin = new ByteArrayInputStream(data);
try {
encode(bin, sw);
}
catch (IOException e) {
// can't happen
}
return sw.toString();
}
public Object toData() {
return data;
}
public static void encode(InputStream in, Appendable sb) throws IOException {
// StringBuilder sb = new StringBuilder();
int buf = 0;
int bits = 0;
int out = 0;
while (true) {
if (bits >= 6) {
bits -= 6;
int v = 0x3F & (buf >> bits);
sb.append(alphabet.charAt(v));
out++;
} else {
int c = in.read();
if (c < 0)
break;
buf <<= 8;
buf |= 0xFF & c;
bits += 8;
}
}
if (bits != 0) {// must be less than 7
sb.append(alphabet.charAt(0x3F & (buf << (6 - bits))));
out++;
}
int mod = 4 - (out % 4);
if (mod != 4) {
for (int i = 0; i < mod; i++)
sb.append('=');
}
}
}