blob: 1210a02dde65aa37b7920a836b1c3cc6c6d889c5 [file] [log] [blame]
Stuart McCulloch26e7a5a2011-10-17 10:31:43 +00001package aQute.lib.base64;
2
3import java.io.*;
4
5/*
6 * Base 64 converter.
7 *
8 * TODO Implement string to byte[]
9 */
10public class Base64 {
11 byte[] data;
12
13 static final String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
14 static byte[] values = new byte[128];
15
16 static {
17 for (int i = 0; i < values.length; i++) {
18 values[i] = -1;
19 }
20 // Create reverse index
21 for (int i = 0; i < alphabet.length(); i++) {
22 char c = alphabet.charAt(i);
23 values[c] = (byte) i;
24 }
25 }
26
27 public Base64(byte data[]) {
28 this.data = data;
29 }
30
31 public final static byte[] decodeBase64(String string) {
32 string = string.trim();
33 ByteArrayOutputStream out = new ByteArrayOutputStream();
34
35 int register = 0;
36 int i = 0;
37 int pads = 0;
38
39 byte test[] = new byte[3];
40
41 while (i < string.length()) {
42 char c = string.charAt(i);
43 if (c > 0x7F)
44 throw new IllegalArgumentException(
45 "Invalid base64 character in " + string
46 + ", character value > 128 ");
47
48 int v = 0;
49 if ( c == '=' ) {
50 pads++;
51 } else {
52 v = values[c];
53 if ( v < 0 )
54 throw new IllegalArgumentException(
55 "Invalid base64 character in " + string + ", " + c );
56 }
57 register <<= 6;
58 register |= v;
59 test[2] = (byte) (register & 0xFF);
60 test[1] = (byte) ((register >> 8) & 0xFF);
61 test[0] = (byte) ((register >> 16) & 0xFF);
62
63 i++;
64
65 if ((i % 4) == 0) {
66 flush(out, register, pads);
67 register = 0;
68 pads = 0;
69 }
70 }
71 return out.toByteArray();
72 }
73
74 static private void flush(ByteArrayOutputStream out, int register, int pads) {
75 switch (pads) {
76 case 0:
77 out.write(0xFF & (register >> 16));
78 out.write(0xFF & (register >> 8));
79 out.write(0xFF & (register >> 0));
80 break;
81
82 case 1:
83 out.write(0xFF & (register >> 16));
84 out.write(0xFF & (register >> 8));
85 break;
86
87 case 2:
88 out.write(0xFF & (register >> 16));
89 }
90 }
91
92 public Base64(String s) {
93 data = decodeBase64(s);
94 }
95
96 public String toString() {
97 return encodeBase64(data);
98 }
99
100 public static String encodeBase64(byte data[]) {
101 StringBuffer sb = new StringBuffer();
102 int buf = 0;
103 int bits = 0;
104 int n = 0;
105
106 while (true) {
107 if (bits >= 6) {
108 bits -= 6;
109 int v = 0x3F & (buf >> bits);
110 sb.append(alphabet.charAt(v));
111 } else {
112 if (n >= data.length)
113 break;
114
115 buf <<= 8;
116 buf |= 0xFF & data[n++];
117 bits += 8;
118 }
119 }
120 if (bits != 0) // must be less than 7
121 sb.append(alphabet.charAt(0x3F & (buf << (6 - bits))));
122
123 int mod = 4 - (sb.length() % 4);
124 if (mod != 4) {
125 for (int i = 0; i < mod; i++)
126 sb.append('=');
127 }
128 return sb.toString();
129 }
130
131 public Object toData() {
132 return data;
133 }
134
135}