KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > sync4j > syncclient > common > Base64


1 /**
2  * Copyright (C) 2003-2005 Funambol
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18
19 package sync4j.syncclient.common;
20
21 /**
22  * $Id: Base64.java,v 1.2 2005/01/19 10:58:31 fabius Exp $
23  *
24  * Just repackaged into sync4j.syncclient.common
25  */

26 public class Base64 {
27     private static final byte[] encodingTable = {
28         (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
29         (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
30         (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
31         (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
32         (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
33         (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
34         (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
35         (byte)'v',
36         (byte)'w', (byte)'x', (byte)'y', (byte)'z',
37         (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6',
38         (byte)'7', (byte)'8', (byte)'9',
39         (byte)'+', (byte)'/'
40     };
41
42     /**
43      * encode the input data producong a base 64 encoded byte array.
44      *
45      * @return a byte array containing the base 64 encoded data.
46      */

47     public static byte[] encode(
48     byte[] data) {
49         byte[] bytes;
50
51         int modulus = data.length % 3;
52         if (modulus == 0) {
53             bytes = new byte[4 * data.length / 3];
54         }
55         else {
56             bytes = new byte[4 * ((data.length / 3) + 1)];
57         }
58
59         int dataLength = (data.length - modulus);
60         int a1, a2, a3;
61         for (int i = 0, j = 0; i < dataLength; i += 3, j += 4) {
62             a1 = data[i] & 0xff;
63             a2 = data[i + 1] & 0xff;
64             a3 = data[i + 2] & 0xff;
65
66             bytes[j] = encodingTable[(a1 >>> 2) & 0x3f];
67             bytes[j + 1] = encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3f];
68             bytes[j + 2] = encodingTable[((a2 << 2) | (a3 >>> 6)) & 0x3f];
69             bytes[j + 3] = encodingTable[a3 & 0x3f];
70         }
71
72                 /*
73                  * process the tail end.
74                  */

75         int b1, b2, b3;
76         int d1, d2;
77
78         switch (modulus) {
79             case 0: /* nothing left to do */
80                 break;
81             case 1:
82                 d1 = data[data.length - 1] & 0xff;
83                 b1 = (d1 >>> 2) & 0x3f;
84                 b2 = (d1 << 4) & 0x3f;
85
86                 bytes[bytes.length - 4] = encodingTable[b1];
87                 bytes[bytes.length - 3] = encodingTable[b2];
88                 bytes[bytes.length - 2] = (byte)'=';
89                 bytes[bytes.length - 1] = (byte)'=';
90                 break;
91             case 2:
92                 d1 = data[data.length - 2] & 0xff;
93                 d2 = data[data.length - 1] & 0xff;
94
95                 b1 = (d1 >>> 2) & 0x3f;
96                 b2 = ((d1 << 4) | (d2 >>> 4)) & 0x3f;
97                 b3 = (d2 << 2) & 0x3f;
98
99                 bytes[bytes.length - 4] = encodingTable[b1];
100                 bytes[bytes.length - 3] = encodingTable[b2];
101                 bytes[bytes.length - 2] = encodingTable[b3];
102                 bytes[bytes.length - 1] = (byte)'=';
103                 break;
104         }
105
106         return bytes;
107     }
108
109         /*
110          * set up the decoding table.
111          */

112     private static final byte[] decodingTable;
113
114     static {
115         decodingTable = new byte[128];
116
117         for (int i = 'A'; i <= 'Z'; i++) {
118             decodingTable[i] = (byte)(i - 'A');
119         }
120
121         for (int i = 'a'; i <= 'z'; i++) {
122             decodingTable[i] = (byte)(i - 'a' + 26);
123         }
124
125         for (int i = '0'; i <= '9'; i++) {
126             decodingTable[i] = (byte)(i - '0' + 52);
127         }
128
129         decodingTable['+'] = 62;
130         decodingTable['/'] = 63;
131     }
132
133     /**
134      * decode the base 64 encoded input data.
135      *
136      * @return a byte array representing the decoded data.
137      */

138     public static byte[] decode(
139     byte[] data) {
140         byte[] bytes;
141         byte b1, b2, b3, b4;
142
143         if (data[data.length - 2] == '=') {
144             bytes = new byte[(((data.length / 4) - 1) * 3) + 1];
145         }
146         else if (data[data.length - 1] == '=') {
147             bytes = new byte[(((data.length / 4) - 1) * 3) + 2];
148         }
149         else {
150             bytes = new byte[((data.length / 4) * 3)];
151         }
152
153         for (int i = 0, j = 0; i < data.length - 4; i += 4, j += 3) {
154             b1 = decodingTable[data[i]];
155             b2 = decodingTable[data[i + 1]];
156             b3 = decodingTable[data[i + 2]];
157             b4 = decodingTable[data[i + 3]];
158
159             bytes[j] = (byte)((b1 << 2) | (b2 >> 4));
160             bytes[j + 1] = (byte)((b2 << 4) | (b3 >> 2));
161             bytes[j + 2] = (byte)((b3 << 6) | b4);
162         }
163
164         if (data[data.length - 2] == '=') {
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             b1 = decodingTable[data[data.length - 4]];
172             b2 = decodingTable[data[data.length - 3]];
173             b3 = decodingTable[data[data.length - 2]];
174
175             bytes[bytes.length - 2] = (byte)((b1 << 2) | (b2 >> 4));
176             bytes[bytes.length - 1] = (byte)((b2 << 4) | (b3 >> 2));
177         }
178         else {
179             b1 = decodingTable[data[data.length - 4]];
180             b2 = decodingTable[data[data.length - 3]];
181             b3 = decodingTable[data[data.length - 2]];
182             b4 = decodingTable[data[data.length - 1]];
183
184             bytes[bytes.length - 3] = (byte)((b1 << 2) | (b2 >> 4));
185             bytes[bytes.length - 2] = (byte)((b2 << 4) | (b3 >> 2));
186             bytes[bytes.length - 1] = (byte)((b3 << 6) | b4);
187         }
188
189         return bytes;
190     }
191
192     /**
193      * decode the base 64 encoded String data.
194      *
195      * @return a byte array representing the decoded data.
196      */

197     public static byte[] decode(
198     String JavaDoc data) {
199         byte[] bytes;
200         byte b1, b2, b3, b4;
201
202         if (data.charAt(data.length() - 2) == '=') {
203             bytes = new byte[(((data.length() / 4) - 1) * 3) + 1];
204         }
205         else if (data.charAt(data.length() - 1) == '=') {
206             bytes = new byte[(((data.length() / 4) - 1) * 3) + 2];
207         }
208         else {
209             bytes = new byte[((data.length() / 4) * 3)];
210         }
211
212         for (int i = 0, j = 0; i < data.length() - 4; i += 4, j += 3) {
213             b1 = decodingTable[data.charAt(i)];
214             b2 = decodingTable[data.charAt(i + 1)];
215             b3 = decodingTable[data.charAt(i + 2)];
216             b4 = decodingTable[data.charAt(i + 3)];
217
218             bytes[j] = (byte)((b1 << 2) | (b2 >> 4));
219             bytes[j + 1] = (byte)((b2 << 4) | (b3 >> 2));
220             bytes[j + 2] = (byte)((b3 << 6) | b4);
221         }
222
223         if (data.charAt(data.length() - 2) == '=') {
224             b1 = decodingTable[data.charAt(data.length() - 4)];
225             b2 = decodingTable[data.charAt(data.length() - 3)];
226
227             bytes[bytes.length - 1] = (byte)((b1 << 2) | (b2 >> 4));
228         }
229         else if (data.charAt(data.length() - 1) == '=') {
230             b1 = decodingTable[data.charAt(data.length() - 4)];
231             b2 = decodingTable[data.charAt(data.length() - 3)];
232             b3 = decodingTable[data.charAt(data.length() - 2)];
233
234             bytes[bytes.length - 2] = (byte)((b1 << 2) | (b2 >> 4));
235             bytes[bytes.length - 1] = (byte)((b2 << 4) | (b3 >> 2));
236         }
237         else {
238             b1 = decodingTable[data.charAt(data.length() - 4)];
239             b2 = decodingTable[data.charAt(data.length() - 3)];
240             b3 = decodingTable[data.charAt(data.length() - 2)];
241             b4 = decodingTable[data.charAt(data.length() - 1)];
242
243             bytes[bytes.length - 3] = (byte)((b1 << 2) | (b2 >> 4));
244             bytes[bytes.length - 2] = (byte)((b2 << 4) | (b3 >> 2));
245             bytes[bytes.length - 1] = (byte)((b3 << 6) | b4);
246         }
247
248         return bytes;
249     }
250 }
Popular Tags