KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > protomatter > util > Base64


1 package com.protomatter.util;
2
3 /**
4  * {{{ The Protomatter Software License, Version 1.0
5  * derived from The Apache Software License, Version 1.1
6  *
7  * Copyright (c) 1998-2002 Nate Sammons. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution,
22  * if any, must include the following acknowledgment:
23  * "This product includes software developed for the
24  * Protomatter Software Project
25  * (http://protomatter.sourceforge.net/)."
26  * Alternately, this acknowledgment may appear in the software itself,
27  * if and wherever such third-party acknowledgments normally appear.
28  *
29  * 4. The names "Protomatter" and "Protomatter Software Project" must
30  * not be used to endorse or promote products derived from this
31  * software without prior written permission. For written
32  * permission, please contact support@protomatter.com.
33  *
34  * 5. Products derived from this software may not be called "Protomatter",
35  * nor may "Protomatter" appear in their name, without prior written
36  * permission of the Protomatter Software Project
37  * (support@protomatter.com).
38  *
39  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
40  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
41  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
42  * DISCLAIMED. IN NO EVENT SHALL THE PROTOMATTER SOFTWARE PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
45  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
46  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
47  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
48  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
49  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE. }}}
51  */

52
53 /**
54  * Base64 encoder/decoder. Does not stream, so be careful with
55  * using large amounts of data.
56  */

57 public class Base64
58 {
59   private Base64()
60   {
61     super();
62   }
63
64   /**
65    * Encode some data and return a String.
66    */

67   public final static String JavaDoc encode(byte[] d)
68   {
69     if (d == null) return null;
70     byte data[] = new byte[d.length+2];
71         System.arraycopy(d, 0, data, 0, d.length);
72     byte dest[] = new byte[(data.length/3)*4];
73
74     // 3-byte to 4-byte conversion
75
for (int sidx = 0, didx=0; sidx < d.length; sidx += 3, didx += 4)
76     {
77       dest[didx] = (byte) ((data[sidx] >>> 2) & 077);
78       dest[didx+1] = (byte) ((data[sidx+1] >>> 4) & 017 |
79                   (data[sidx] << 4) & 077);
80       dest[didx+2] = (byte) ((data[sidx+2] >>> 6) & 003 |
81                   (data[sidx+1] << 2) & 077);
82       dest[didx+3] = (byte) (data[sidx+2] & 077);
83     }
84
85     // 0-63 to ascii printable conversion
86
for (int idx = 0; idx <dest.length; idx++)
87     {
88       if (dest[idx] < 26) dest[idx] = (byte)(dest[idx] + 'A');
89       else if (dest[idx] < 52) dest[idx] = (byte)(dest[idx] + 'a' - 26);
90       else if (dest[idx] < 62) dest[idx] = (byte)(dest[idx] + '0' - 52);
91       else if (dest[idx] < 63) dest[idx] = (byte)'+';
92       else dest[idx] = (byte)'/';
93     }
94
95     // add padding
96
for (int idx = dest.length-1; idx > (d.length*4)/3; idx--)
97     {
98       dest[idx] = (byte)'=';
99     }
100     return new String JavaDoc(dest);
101   }
102
103   /**
104    * Decode data and return bytes.
105    */

106   public final static byte[] decode(String JavaDoc str)
107   {
108     if (str == null) return null;
109     return decode(str.getBytes());
110   }
111
112   /**
113    * Decode data and return bytes. Assumes that the data passed
114    * in is ASCII text.
115    */

116   public final static byte[] decode(byte[] data)
117   {
118     int tail = data.length;
119     while (data[tail-1] == '=') tail--;
120     byte dest[] = new byte[tail - data.length/4];
121
122     // ascii printable to 0-63 conversion
123
for (int idx = 0; idx <data.length; idx++)
124     {
125       if (data[idx] == '=') data[idx] = 0;
126       else if (data[idx] == '/') data[idx] = 63;
127       else if (data[idx] == '+') data[idx] = 62;
128       else if (data[idx] >= '0' && data[idx] <= '9')
129         data[idx] = (byte)(data[idx] - ('0' - 52));
130       else if (data[idx] >= 'a' && data[idx] <= 'z')
131         data[idx] = (byte)(data[idx] - ('a' - 26));
132       else if (data[idx] >= 'A' && data[idx] <= 'Z')
133         data[idx] = (byte)(data[idx] - 'A');
134     }
135
136     // 4-byte to 3-byte conversion
137
int sidx, didx;
138     for (sidx = 0, didx=0; didx < dest.length-2; sidx += 4, didx += 3)
139     {
140       dest[didx] = (byte) ( ((data[sidx] << 2) & 255) |
141               ((data[sidx+1] >>> 4) & 3) );
142       dest[didx+1] = (byte) ( ((data[sidx+1] << 4) & 255) |
143               ((data[sidx+2] >>> 2) & 017) );
144       dest[didx+2] = (byte) ( ((data[sidx+2] << 6) & 255) |
145               (data[sidx+3] & 077) );
146     }
147     if (didx < dest.length)
148     {
149       dest[didx] = (byte) ( ((data[sidx] << 2) & 255) |
150               ((data[sidx+1] >>> 4) & 3) );
151     }
152     if (++didx < dest.length)
153     {
154       dest[didx] = (byte) ( ((data[sidx+1] << 4) & 255) |
155               ((data[sidx+2] >>> 2) & 017) );
156     }
157     return dest;
158   }
159
160   /**
161    * A simple test that encodes and decodes the first commandline argument.
162    */

163   public static final void main(String JavaDoc args[])
164   {
165     if (args.length != 1)
166     {
167       System.out.println("Usage: Base64 string");
168       System.exit(0);
169     }
170     try
171     {
172       String JavaDoc e = Base64.encode(args[0].getBytes());
173       String JavaDoc d = new String JavaDoc(Base64.decode(e));
174       System.out.println("Input = '" + args[0] + "'");
175       System.out.println("Encoded = '" + e + "'");
176       System.out.println("Decoded = '" + d + "'");
177     }
178     catch (Exception JavaDoc x)
179     {
180       x.printStackTrace();
181     }
182   }
183 }
184
185
Popular Tags