cleanup
[org.ibex.crypto.git] / src / org / ibex / crypto / Base64.java
1 /*
2  * org.ibex.crypto.Base64 - By Brian Alliet
3  * Copyright (C) 2004 Brian Alliet
4  */
5 package org.ibex.crypto;
6
7 import java.io.UnsupportedEncodingException;
8
9 public final class Base64 {
10         private Base64() { /* can't be instansiated */ }
11         
12     private static final char encodeMap[] = {
13         'A','B','C','D','E','F','G','H',
14         'I','J','K','L','M','N','O','P',
15         'Q','R','S','T','U','V','W','X',
16         'Y','Z','a','b','c','d','e','f',
17         'g','h','i','j','k','l','m','n',
18         'o','p','q','r','s','t','u','v',
19         'w','x','y','z','0','1','2','3',
20         '4','5','6','7','8','9','+','/'
21     };
22
23     private static final int decodeMap[] = {
24         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
25         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
26         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,
27         52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,
28         -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,
29         15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,
30         -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
31         41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1
32     };
33
34         public static void main(String[] args){
35         if(args.length == 2 && args[0].equals("encode"))
36             System.out.println(encode(args[1].getBytes()));
37         else if(args.length == 2 && args[0].equals("decode"))
38             System.out.println(new String(decode(args[1])));
39         else {
40             System.out.println("Usage: Base64 {encode,decode} text");
41             System.exit(1);
42         }
43         System.exit(0);
44         }
45         
46         public static byte[] decode(String inString){
47         char[] in = inString.toCharArray();
48         int part=0;
49         int theBytes = 0;
50         byte[] out = new byte[in.length / 4 * 3];
51         int outPos = 0;
52         for(int i=0;i<in.length;i++){
53             int x = decodeMap[in[i] & 0x7f];
54             if(x == -1) continue;
55             if(x == -2) break;
56             theBytes = (theBytes << 6) | x;
57             part++;
58             if(part == 4){
59                 part = 0;
60                 out[outPos++] = (byte)((theBytes >>> 16) & 0xff);
61                 out[outPos++] = (byte)((theBytes >>>  8) & 0xff);
62                 out[outPos++] = (byte)((theBytes >>>  0) & 0xff);
63             }
64         }
65         switch(part){
66             case 3:
67                 out[outPos++] = (byte)((theBytes >>> 10) & 0xff);
68                 out[outPos++] = (byte)((theBytes >>> 2) & 0xff);
69                 break;
70             case 2: 
71                 out[outPos++] = (byte)((theBytes >> 4) & 0xff);
72                 break;
73         }
74         
75         if(outPos < out.length){
76             byte[] a = new byte[outPos];
77             System.arraycopy(out,0,a,0,outPos);
78             return a;
79         } else {
80             return out;
81         }
82     }
83
84         public static String encode(String in) { return encode(getBytes(in)); }
85     public static String encode(byte[] in){
86         int part=0;
87         int theBytes = 0;
88         char[] out = new char[(in.length / 3 + 1) * 4];
89         int outPos = 0;
90         for(int i=0;i<in.length;i++){
91             theBytes = (theBytes << 8) | in[i];
92             part++;
93             if(part == 3){
94                 part = 0;
95                 out[outPos++] = encodeMap[(theBytes >>> 18) & 0x3f];
96                 out[outPos++] = encodeMap[(theBytes >>> 12) & 0x3f];
97                 out[outPos++] = encodeMap[(theBytes >>>  6) & 0x3f];
98                 out[outPos++] = encodeMap[(theBytes >>>  0) & 0x3f];
99             }
100         }
101         switch(part){
102             case 2:
103                 out[outPos++] = encodeMap[(theBytes >>>  10) & 0x3f];
104                 out[outPos++] = encodeMap[(theBytes >>>  4)  & 0x3f];
105                 out[outPos++] = encodeMap[(theBytes <<   2)  & 0x3f];
106                 out[outPos++] = '=';
107                 break;
108             case 1:
109                 out[outPos++] = encodeMap[(theBytes >>> 2) & 0x3f];
110                 out[outPos++] = encodeMap[(theBytes <<  4) & 0x3f];
111                 out[outPos++] = '=';
112                 out[outPos++] = '=';
113                 break;
114         }
115         return new String(out,0,outPos);
116     }
117     
118     public static byte[] getBytes(String s) {
119         try {
120                 return s.getBytes("US-ASCII");
121         } catch (UnsupportedEncodingException e) {
122                 throw new Error("should never happen");
123         }
124     }
125 }