2002/03/21 01:19:32
[org.ibex.core.git] / src / org / bouncycastle / util / encoders / Base64.java
1 package org.bouncycastle.util.encoders;
2
3 public class Base64
4 {
5         private static byte[] encodingTable =
6                 {
7                     (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
8             (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
9             (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
10             (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
11                     (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
12             (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
13             (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
14             (byte)'v',
15                     (byte)'w', (byte)'x', (byte)'y', (byte)'z',
16                     (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6',
17             (byte)'7', (byte)'8', (byte)'9',
18                     (byte)'+', (byte)'/'
19                 };
20
21         /**
22          * encode the input data producong a base 64 encoded byte array.
23          *
24          * @return a byte array containing the base 64 encoded data.
25          */
26         public static byte[] encode(
27                 byte[]  data)
28         {
29                 byte[]  bytes;
30
31                 if ((data.length % 3) == 0)
32                 {
33                         bytes = new byte[4 * data.length / 3];
34                 }
35                 else
36                 {
37                         bytes = new byte[4 * ((data.length / 3) + 1)];
38                 }
39
40                 for (int i = 0, j = 0;
41                                 i < ((data.length / 3) * 3); i += 3, j += 4)
42                 {
43                         int     b1, b2, b3, b4;
44                         int     d1, d2, d3;
45
46                         d1 = data[i] & 0xff;
47                         d2 = data[i + 1] & 0xff;
48                         d3 = data[i + 2] & 0xff;
49
50                         b1 = (d1 >>> 2) & 0x3f;
51                         b2 = ((d1 << 4) | (d2 >>> 4)) & 0x3f;
52                         b3 = ((d2 << 2) | (d3 >>> 6)) & 0x3f;
53                         b4 = d3 & 0x3f;
54
55                         bytes[j] = encodingTable[b1];
56                         bytes[j + 1] = encodingTable[b2];
57                         bytes[j + 2] = encodingTable[b3];
58                         bytes[j + 3] = encodingTable[b4];
59                 }
60
61                 /*
62                  * process the tail end.
63                  */
64                 int     b1, b2, b3;
65                 int     d1, d2;
66
67                 switch (data.length % 3)
68                 {
69                 case 0:         /* nothing left to do */
70                         break;
71                 case 1:
72                         d1 = data[data.length - 1] & 0xff;
73                         b1 = (d1 >>> 2) & 0x3f;
74                         b2 = (d1 << 4) & 0x3f;
75
76                         bytes[bytes.length - 4] = encodingTable[b1];
77                         bytes[bytes.length - 3] = encodingTable[b2];
78                         bytes[bytes.length - 2] = (byte)'=';
79                         bytes[bytes.length - 1] = (byte)'=';
80                         break;
81                 case 2:
82                         d1 = data[data.length - 2] & 0xff;
83                         d2 = data[data.length - 1] & 0xff;
84
85                         b1 = (d1 >>> 2) & 0x3f;
86                         b2 = ((d1 << 4) | (d2 >>> 4)) & 0x3f;
87                         b3 = (d2 << 2) & 0x3f;
88
89                         bytes[bytes.length - 4] = encodingTable[b1];
90                         bytes[bytes.length - 3] = encodingTable[b2];
91                         bytes[bytes.length - 2] = encodingTable[b3];
92                         bytes[bytes.length - 1] = (byte)'=';
93                         break;
94                 }
95
96                 return bytes;
97         }
98
99         /*
100          * set up the decoding table.
101          */
102         private static byte[] decodingTable;
103
104         static
105         {
106                 decodingTable = new byte[128];
107
108                 for (int i = 'A'; i <= 'Z'; i++)
109                 {
110                         decodingTable[i] = (byte)(i - 'A');
111                 }
112
113                 for (int i = 'a'; i <= 'z'; i++)
114                 {
115                         decodingTable[i] = (byte)(i - 'a' + 26);
116                 }
117
118                 for (int i = '0'; i <= '9'; i++)
119                 {
120                         decodingTable[i] = (byte)(i - '0' + 52);
121                 }
122
123                 decodingTable['+'] = 62;
124                 decodingTable['/'] = 63;
125         }
126
127         /**
128          * decode the base 64 encoded input data.
129          *
130          * @return a byte array representing the decoded data.
131          */
132         public static byte[] decode(
133                 byte[]  data)
134         {
135                 byte[]  bytes;
136                 byte    b1, b2, b3, b4;
137
138                 if (data[data.length - 2] == '=')
139                 {
140                         bytes = new byte[(((data.length / 4) - 1) * 3) + 1];
141                 }
142                 else if (data[data.length - 1] == '=')
143                 {
144                         bytes = new byte[(((data.length / 4) - 1) * 3) + 2];
145                 }
146                 else
147                 {
148                         bytes = new byte[((data.length / 4) * 3)];
149                 }
150
151                 for (int i = 0, j = 0; i < data.length - 4; i += 4, j += 3)
152                 {
153                         b1 = decodingTable[data[i]];
154                         b2 = decodingTable[data[i + 1]];
155                         b3 = decodingTable[data[i + 2]];
156                         b4 = decodingTable[data[i + 3]];
157
158                         bytes[j] = (byte)((b1 << 2) | (b2 >> 4));
159                         bytes[j + 1] = (byte)((b2 << 4) | (b3 >> 2));
160                         bytes[j + 2] = (byte)((b3 << 6) | b4);
161                 }
162
163                 if (data[data.length - 2] == '=')
164                 {
165                         b1 = decodingTable[data[data.length - 4]];
166                         b2 = decodingTable[data[data.length - 3]];
167
168                         bytes[bytes.length - 1] = (byte)((b1 << 2) | (b2 >> 4));
169                 }
170                 else if (data[data.length - 1] == '=')
171                 {
172                         b1 = decodingTable[data[data.length - 4]];
173                         b2 = decodingTable[data[data.length - 3]];
174                         b3 = decodingTable[data[data.length - 2]];
175
176                         bytes[bytes.length - 2] = (byte)((b1 << 2) | (b2 >> 4));
177                         bytes[bytes.length - 1] = (byte)((b2 << 4) | (b3 >> 2));
178                 }
179                 else
180                 {
181                         b1 = decodingTable[data[data.length - 4]];
182                         b2 = decodingTable[data[data.length - 3]];
183                         b3 = decodingTable[data[data.length - 2]];
184                         b4 = decodingTable[data[data.length - 1]];
185
186                         bytes[bytes.length - 3] = (byte)((b1 << 2) | (b2 >> 4));
187                         bytes[bytes.length - 2] = (byte)((b2 << 4) | (b3 >> 2));
188                         bytes[bytes.length - 1] = (byte)((b3 << 6) | b4);
189                 }
190
191                 return bytes;
192         }
193
194         /**
195          * decode the base 64 encoded String data.
196          *
197          * @return a byte array representing the decoded data.
198          */
199         public static byte[] decode(
200                 String  data)
201         {
202                 byte[]  bytes;
203                 byte    b1, b2, b3, b4;
204
205                 if (data.charAt(data.length() - 2) == '=')
206                 {
207                         bytes = new byte[(((data.length() / 4) - 1) * 3) + 1];
208                 }
209                 else if (data.charAt(data.length() - 1) == '=')
210                 {
211                         bytes = new byte[(((data.length() / 4) - 1) * 3) + 2];
212                 }
213                 else
214                 {
215                         bytes = new byte[((data.length() / 4) * 3)];
216                 }
217
218                 for (int i = 0, j = 0; i < data.length() - 4; i += 4, j += 3)
219                 {
220                         b1 = decodingTable[data.charAt(i)];
221                         b2 = decodingTable[data.charAt(i + 1)];
222                         b3 = decodingTable[data.charAt(i + 2)];
223                         b4 = decodingTable[data.charAt(i + 3)];
224
225                         bytes[j] = (byte)((b1 << 2) | (b2 >> 4));
226                         bytes[j + 1] = (byte)((b2 << 4) | (b3 >> 2));
227                         bytes[j + 2] = (byte)((b3 << 6) | b4);
228                 }
229
230                 if (data.charAt(data.length() - 2) == '=')
231                 {
232                         b1 = decodingTable[data.charAt(data.length() - 4)];
233                         b2 = decodingTable[data.charAt(data.length() - 3)];
234
235                         bytes[bytes.length - 1] = (byte)((b1 << 2) | (b2 >> 4));
236                 }
237                 else if (data.charAt(data.length() - 1) == '=')
238                 {
239                         b1 = decodingTable[data.charAt(data.length() - 4)];
240                         b2 = decodingTable[data.charAt(data.length() - 3)];
241                         b3 = decodingTable[data.charAt(data.length() - 2)];
242
243                         bytes[bytes.length - 2] = (byte)((b1 << 2) | (b2 >> 4));
244                         bytes[bytes.length - 1] = (byte)((b2 << 4) | (b3 >> 2));
245                 }
246                 else
247                 {
248                         b1 = decodingTable[data.charAt(data.length() - 4)];
249                         b2 = decodingTable[data.charAt(data.length() - 3)];
250                         b3 = decodingTable[data.charAt(data.length() - 2)];
251                         b4 = decodingTable[data.charAt(data.length() - 1)];
252
253                         bytes[bytes.length - 3] = (byte)((b1 << 2) | (b2 >> 4));
254                         bytes[bytes.length - 2] = (byte)((b2 << 4) | (b3 >> 2));
255                         bytes[bytes.length - 1] = (byte)((b3 << 6) | b4);
256                 }
257
258                 return bytes;
259         }
260 }