KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > snipsnap > util > Base64


1 package org.snipsnap.util;
2
3 /**
4  * Does Base64 encoding/decoding as described in section (6.8.) of RFC 2045.
5  */

6 public class Base64 {
7     
8     /**
9      * the Base64 translation table; does the same as 'encode()', but
10      * this way decoding should be faster.
11      */

12     public final static char[] translationTable = new char[]{
13         'A','B','C','D','E','F','G','H','I','J','K','L','M',
14         'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
15         'a','b','c','d','e','f','g','h','i','j','k','l','m',
16         'n','o','p','q','r','s','t','u','v','w','x','y','z',
17         '0','1','2','3','4','5','6','7','8','9','+','/'
18     };
19     
20     /* line break characters for use in encoding output */
21     private static char[] lbcs = {'\r','\n'};
22
23     /**
24      * Encode string to Base64 formatted char array.
25      * @param text This argument must contain the text or binary data that shall be
26      * encoded. This version of the 'encode()' method accepts a String and
27      * converts all line breaks to CRLF (or whatever else you have
28      * defined by using 'setLbcs()') prior to encoding.
29      * "CRLF" is equal to the Java string "\r\n".
30      */

31     public static char[] encode(String JavaDoc text) {
32         if(text == null) { return null; }
33         return encode(convertCRLF((String JavaDoc)text).toCharArray());
34     }
35      
36     /**
37      * Encode char array to Base64 formatted char array.
38      * @param text This argument must contain the text or binary data that shall be
39      * encoded. This version of the 'encode()' method accepts a char array
40      * as input and will - in contrast to the other 'encode()' method -
41      * not try to do any conversion at all.
42      */

43     public static char[] encode(char[] text) {
44         if(text == null) { return null; }
45         char[] a = text;
46         
47         /* we first need to calculate the size of our base64 encoded array */
48         int size = a.length / 3 * 4;
49         if(a.length % 3 > 0) {
50             size += 4;
51         }
52         /* + line break characters */
53         if(size % 68 > 0) {
54           size += (size / 68 + 1) * lbcs.length;
55         } else {
56             size += (size / 68) * lbcs.length;
57         }
58         
59         /* encoding... */
60         char[] b = new char[size];
61         int p = 0;
62         int wp = 0;
63         int lc = 0;
64         int[] y = new int[4];
65         /* encode 24 bit entities */
66         while(p / 3 < a.length / 3) {
67             y[0] = (a[p] & 252) >>> 2;
68             y[1] = (a[p] & 3) << 4 | (a[p+1] & 240) >>> 4;
69             y[2] = (a[p+1] & 15) << 2 | (a[p+2] & 192) >>> 6;
70             y[3] = a[p+2] & 63;
71             for(int i = 0; i < 4; i++) {
72                 b[wp++] = translationTable[y[i]];
73             }
74             lc++;
75             /* 68 characters per line */
76             if(lc == 17) {
77                 for(int i = 0; i < lbcs.length; i++) {
78                     b[wp++] = lbcs[i];
79                 }
80                 lc = 0;
81             }
82             p += 3;
83         }
84         /* encode remaining partial entities (8 or 16 bits) */
85         if(a.length - p == 1) {
86             y[0] = (a[p] & 252) >>> 2;
87             y[1] = (a[p] & 3) << 4;
88             for(int i = 0; i < 2; i++) {
89                 b[wp++] = translationTable[y[i]];
90             }
91             b[wp++] = '=';
92             b[wp++] = '=';
93             lc++;
94         } else
95         if(a.length - p == 2) {
96             y[0] = (a[p] & 252) >>> 2;
97             y[1] = (a[p] & 3) << 4 | (a[p+1] & 240) >>> 4;
98             y[2] = (a[p+1] & 15) << 2;
99             for(int i = 0; i < 3; i++) {
100                 b[wp++] = translationTable[y[i]];
101             }
102             b[wp++] = '=';
103             lc++;
104         }
105         /* don't forget final line break */
106         if(lc > 0) {
107             for(int i = 0; i < lbcs.length; i++) {
108                 b[wp++] = lbcs[i];
109             }
110         }
111         return b;
112     }
113     
114     /**
115      * Decodes Base64 formatted byte array or string into a char array.
116      * @param text This argument must contain the text or data as a string
117      * object which shall be decoded.
118      */

119     public static char[] decode(String JavaDoc text) {
120         return decode(text.toCharArray());
121     }
122     
123     public static byte[] decodeToByteArray(String JavaDoc text) {
124         return charArrayToByteArray(decode(text.toCharArray()));
125     }
126      
127     public static byte[] decodeToByteArray(char[] text) {
128         return charArrayToByteArray(decode(text));
129     }
130
131     /**
132      * Decodes Base64 formatted byte array or string into a char array.
133      * @param text This argument must contain the text or data as a char
134      * array object which shall be decoded.
135      */

136     public static char[] decode(char[] text) {
137         if(text == null) { return null; }
138         char[] a = text;
139         
140         /* remove all junk */
141         int p = 0; // read position
142
int wp = 0; // write position
143
while(p < a.length && a[p] != '=') {
144             if(a[p] >= 'a' && a[p] <= 'z' || a[p] >= 'A' && a[p] <= 'Z' ||
145                a[p] >= '0' && a[p] <= '9' || a[p] == '+' || a[p] == '/') {
146                 a[wp++] = a[p];
147             }
148             p++;
149         }
150         int len = wp;
151         
152         /* now calculate the size of our decoded byte array */
153         int size = len / 4 * 3;
154         if(len % 4 == 2) {
155             size++;
156         } else
157         if(len % 4 == 3) {
158             size += 2;
159         }
160         
161         /* decoding... */
162         char[] b = new char[size];
163         int rp = 0;
164         wp = 0;
165         while(rp/4 < len/4) {
166             b[wp++] = (char) (decode(a[rp]) << 2 | (decode(a[rp+1]) & 48) >> 4);
167             b[wp++] = (char) ((decode(a[rp+1]) & 15) << 4 | (decode(a[rp+2]) & 60) >> 2);
168             b[wp++] = (char) ((decode(a[rp+2]) & 3) << 6 | decode(a[rp+3]));
169             rp += 4;
170         }
171         /* is there at least one more character to decode? */
172         if(len - rp >= 2) {
173             b[wp++] = (char) (decode(a[rp]) << 2 | (decode(a[rp+1]) & 48) >> 4);
174         }
175         /* is there a second chracter to decode? */
176         if(len - rp == 3) {
177             b[wp++] = (char) ((decode(a[rp+1]) & 15) << 4 | (decode(a[rp+2]) & 60) >> 2);
178         }
179         return b;
180     }
181     
182     /**
183      * Decodes a Base64 character into its 6-bit value (0..63).
184      */

185     public static char decode(char a) {
186         if(a >= 'A' && a <= 'Z') {
187             return (char) (a-'A');
188         }
189         if(a >= 'a' && a <= 'z') {
190             return (char) (26+a-'a');
191         }
192         if(a >= '0' && a <= '9') {
193             return (char) (52+a-'0');
194         }
195         if(a == '+') {
196             return (char) 62;
197         }
198         return (char) 63;
199     }
200     
201     /**
202      * Encodes a 6-bit value (0..63) into a Base64 character.
203      */

204     public static char encode(int a) {
205         if(a >= 0 && a <= 25) {
206             return (char) (a+'A');
207         }
208         if(a >= 26 && a <= 51) {
209             return (char) (a-26+'a');
210         }
211         if(a >= 52 && a <= 61) {
212             return (char) (a-52+'0');
213         }
214         if(a == 62) {
215             return (char) '+';
216         }
217         return (char) '/';
218     }
219     
220     /**
221      * set the line break chracters for use in encoding output. Default is
222      * '\r\n'.
223      */

224     public static void setLbcs(char[] l) {
225         lbcs = l;
226     }
227     
228     /**
229      * convert '\n'-line breaks to '\r\n'-line breaks.
230      */

231     private static String JavaDoc convertCRLF(String JavaDoc text) {
232         if(text.length() == 0) {
233             return text;
234         }
235         StringBuffer JavaDoc t = new StringBuffer JavaDoc(text);
236         int p = 0;
237         if(t.charAt(p) == '\n') {
238             t.insert(p,'\r');
239             p++;
240         }
241         p++;
242         while( p < t.length() ) {
243             if(t.charAt(p) == '\n' && t.charAt(p-1) != '\r') {
244                 t.insert(p,'\r');
245                 p++;
246             }
247             p++;
248         }
249         return t.toString();
250     }
251     
252     private static byte[] charArrayToByteArray(char[] a) {
253         if(a == null || a.length == 0) { return null; }
254         byte[] b = new byte[a.length];
255         for(int i = 0; i < a.length; i++) {
256             b[i] = (byte) a[i];
257         }
258         return b;
259     }
260 }
261
Popular Tags