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