Base64.java

00001 
00024 package org.objectweb.jonas.security.realm.lib;
00025 
00036 public class Base64 {
00037 
00041     private static char[] alphabet =
00042         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
00043         .toCharArray();
00044 
00048     private static byte[] codes = new byte[256];
00049 
00050     static {
00051         for (int i = 0; i < 256; i++) {
00052             codes[i] = -1;
00053         }
00054         for (int i = 'A'; i <= 'Z'; i++) {
00055             codes[i] = (byte) (i - 'A');
00056         }
00057         for (int i = 'a'; i <= 'z'; i++) {
00058             codes[i] = (byte) (26 + i - 'a');
00059         }
00060         for (int i = '0'; i <= '9'; i++) {
00061             codes[i] = (byte) (52 + i - '0');
00062         }
00063         codes['+'] = 62;
00064         codes['/'] = 63;
00065     }
00066 
00067 
00068 
00076     public static char[] encode(byte[] data) {
00077         char[] out = new char[((data.length + 2) / 3) * 4];
00078 
00079         //
00080         // 3 bytes encode to 4 chars.  Output is always an even
00081         // multiple of 4 characters.
00082         //
00083         for (int i = 0, index = 0; i < data.length; i += 3, index += 4) {
00084             boolean quad = false;
00085             boolean trip = false;
00086 
00087             int val = (0xFF & (int) data[i]);
00088             val <<= 8;
00089             if ((i + 1) < data.length) {
00090                 val |= (0xFF & (int) data[i + 1]);
00091                 trip = true;
00092             }
00093             val <<= 8;
00094             if ((i + 2) < data.length) {
00095                 val |= (0xFF & (int) data[i + 2]);
00096                 quad = true;
00097             }
00098             out[index + 3] = alphabet[(quad ? (val & 0x3F) : 64)];
00099             val >>= 6;
00100             out[index + 2] = alphabet[(trip ? (val & 0x3F) : 64)];
00101             val >>= 6;
00102             out[index + 1] = alphabet[val & 0x3F];
00103             val >>= 6;
00104             out[index + 0] = alphabet[val & 0x3F];
00105         }
00106         return out;
00107     }
00108 
00122     public static byte[] decode(char[] data) {
00123         // as our input could contain non-BASE64 data (newlines,
00124         // whitespace of any sort, whatever) we must first adjust
00125         // our count of USABLE data so that...
00126         // (a) we don't misallocate the output array, and
00127         // (b) think that we miscalculated our data length
00128         //     just because of extraneous throw-away junk
00129 
00130         int tempLen = data.length;
00131         for (int ix = 0; ix < data.length; ix++) {
00132             if ((data[ix] > 255) || codes[ data[ix] ] < 0) {
00133                 --tempLen;  // ignore non-valid chars and padding
00134             }
00135         }
00136         // calculate required length:
00137         //  -- 3 bytes for every 4 valid base64 chars
00138         //  -- plus 2 bytes if there are 3 extra base64 chars,
00139         //     or plus 1 byte if there are 2 extra.
00140 
00141         int len = (tempLen / 4) * 3;
00142         if ((tempLen % 4) == 3) {
00143             len += 2;
00144         }
00145         if ((tempLen % 4) == 2) {
00146             len += 1;
00147         }
00148 
00149         byte[] out = new byte[len];
00150 
00151 
00152 
00153         int shift = 0;   // # of excess bits stored in accum
00154         int accum = 0;   // excess bits
00155         int index = 0;
00156 
00157         // we now go through the entire array (NOT using the 'tempLen' value)
00158         for (int ix = 0; ix < data.length; ix++) {
00159             int value = (data[ix] > 255) ? -1 : codes[ data[ix] ];
00160 
00161             if (value >= 0) {           // skip over non-code
00162                 accum <<= 6;            // bits shift up by 6 each time thru
00163                 shift += 6;             // loop, with new bits being put in
00164                 accum |= value;         // at the bottom.
00165                 if (shift >= 8) {       // whenever there are 8 or more shifted in,
00166                     shift -= 8;         // write them out (from the top, leaving any
00167                     out[index++] =      // excess at the bottom for next iteration.
00168                         (byte) ((accum >> shift) & 0xff);
00169                 }
00170             }
00171             // we will also have skipped processing a padding null byte ('=') here;
00172             // these are used ONLY for padding to an even length and do not legally
00173             // occur as encoded data. for this reason we can ignore the fact that
00174             // no index++ operation occurs in that special case: the out[] array is
00175             // initialized to all-zero bytes to start with and that works to our
00176             // advantage in this combination.
00177         }
00178 
00179         // if there is STILL something wrong we just have to throw up now!
00180         if (index != out.length) {
00181             throw new Error("Miscalculated data length (wrote " + index + " instead of " + out.length + ")");
00182         }
00183 
00184         return out;
00185     }
00186 
00187 
00188 
00189 }

Generated on Tue Feb 15 15:05:22 2005 for JOnAS by  doxygen 1.3.9.1