Source for gnu.java.net.BASE64

   1: /* BASE.java --
   2:    Copyright (C) 2003, 2004, 2005  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10:  
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package gnu.java.net;
  40: 
  41: /**
  42:  * Encodes and decodes text according to the BASE64 encoding.
  43:  *
  44:  * @author Chris Burdess (dog@gnu.org)
  45:  */
  46: public final class BASE64
  47: {
  48:   private static final byte[] src = {
  49:     0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
  50:     0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54,
  51:     0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64,
  52:     0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
  53:     0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
  54:     0x79, 0x7a, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  55:     0x38, 0x39, 0x2b, 0x2f
  56:   };
  57: 
  58:   private static final byte[] dst;
  59:   static
  60:   {
  61:     dst = new byte[0x100];
  62:     for (int i = 0x0; i < 0xff; i++)
  63:       {
  64:         dst[i] = -1;
  65:       }
  66:     for (int i = 0; i < src.length; i++)
  67:       {
  68:         dst[src[i]] = (byte) i;
  69:       }
  70:   }
  71: 
  72:   private BASE64()
  73:   {
  74:   }
  75: 
  76:   /**
  77:    * Encode the specified byte array using the BASE64 algorithm.
  78:    *
  79:    * @param bs the source byte array
  80:    */
  81:   public static byte[] encode(byte[] bs)
  82:   {
  83:     int si = 0, ti = 0;         // source/target array indices
  84:     byte[] bt = new byte[((bs.length + 2) * 4) / 3];     // target byte array
  85:     for (; si < bs.length; si += 3)
  86:       {
  87:         int buflen = bs.length - si;
  88:         if (buflen == 1)
  89:           {
  90:             byte b = bs[si];
  91:             int i = 0;
  92:             bt[ti++] = src[b >>> 2 & 0x3f];
  93:             bt[ti++] = src[(b << 4 & 0x30) + (i >>> 4 & 0xf)];
  94:           }
  95:         else if (buflen == 2)
  96:           {
  97:             byte b1 = bs[si], b2 = bs[si + 1];
  98:             int i = 0;
  99:             bt[ti++] = src[b1 >>> 2 & 0x3f];
 100:             bt[ti++] = src[(b1 << 4 & 0x30) + (b2 >>> 4 & 0xf)];
 101:             bt[ti++] = src[(b2 << 2 & 0x3c) + (i >>> 6 & 0x3)];
 102:           }
 103:         else
 104:           {
 105:             byte b1 = bs[si], b2 = bs[si + 1], b3 = bs[si + 2];
 106:             bt[ti++] = src[b1 >>> 2 & 0x3f];
 107:             bt[ti++] = src[(b1 << 4 & 0x30) + (b2 >>> 4 & 0xf)];
 108:             bt[ti++] = src[(b2 << 2 & 0x3c) + (b3 >>> 6 & 0x3)];
 109:             bt[ti++] = src[b3 & 0x3f];
 110:           }
 111:       }
 112:      if (ti < bt.length)
 113:       {
 114:     byte[] tmp = new byte[ti];
 115:     System.arraycopy(bt, 0, tmp, 0, ti);
 116:     bt = tmp;
 117:       }
 118:     /*while (ti < bt.length)
 119:       {
 120:         bt[ti++] = 0x3d;
 121:       }*/
 122:     return bt;
 123:   }
 124: 
 125:   /**
 126:    * Decode the specified byte array using the BASE64 algorithm.
 127:    *
 128:    * @param bs the source byte array
 129:    */
 130:   public static byte[] decode(byte[] bs)
 131:   {
 132:     int srclen = bs.length;
 133:     while (srclen > 0 && bs[srclen - 1] == 0x3d)
 134:       {
 135:         srclen--; /* strip padding character */
 136:       }
 137:     byte[] buffer = new byte[srclen];
 138:     int buflen = 0;
 139:     int si = 0;
 140:     int len = srclen - si;
 141:     while (len > 0)
 142:       {
 143:         byte b0 = dst[bs[si++] & 0xff];
 144:         byte b2 = dst[bs[si++] & 0xff];
 145:         buffer[buflen++] = (byte) (b0 << 2 & 0xfc | b2 >>> 4 & 0x3);
 146:         if (len > 2)
 147:           {
 148:             b0 = b2;
 149:             b2 = dst[bs[si++] & 0xff];
 150:             buffer[buflen++] = (byte) (b0 << 4 & 0xf0 | b2 >>> 2 & 0xf);
 151:             if (len > 3)
 152:               {
 153:                 b0 = b2;
 154:                 b2 = dst[bs[si++] & 0xff];
 155:                 buffer[buflen++] = (byte) (b0 << 6 & 0xc0 | b2 & 0x3f);
 156:               }
 157:           }
 158:         len = srclen - si;
 159:       }
 160:     byte[] bt = new byte[buflen];
 161:     System.arraycopy(buffer, 0, bt, 0, buflen);
 162:     return bt;
 163:   }
 164:   
 165:   public static void main(String[] args)
 166:   {
 167:     boolean decode = false;
 168:     for (int i = 0; i < args.length; i++)
 169:       {
 170:         if (args[i].equals("-d"))
 171:           {
 172:             decode = true;
 173:           }
 174:         else
 175:           {
 176:             try
 177:               {
 178:                 byte[] in = args[i].getBytes("US-ASCII");
 179:                 byte[] out = decode ? decode(in) : encode(in);
 180:                 System.out.println(args[i] + " = " +
 181:                                    new String(out, "US-ASCII"));
 182:               }
 183:             catch (java.io.UnsupportedEncodingException e)
 184:               {
 185:                 e.printStackTrace(System.err);
 186:               }
 187:           }
 188:       }
 189:   }
 190: }