Initial revision
[old-projects.git] / ekit / com / hexidec / util / Base64Codec.java
1 package com.hexidec.util;
2
3 import java.util.Vector;
4
5 public class Base64Codec
6 {
7 public static Vector Base64Tokens = new Vector(64);
8 static
9 {
10 Base64Tokens.add("A");
11 Base64Tokens.add("B");
12 Base64Tokens.add("C");
13 Base64Tokens.add("D");
14 Base64Tokens.add("E");
15 Base64Tokens.add("F");
16 Base64Tokens.add("G");
17 Base64Tokens.add("H");
18 Base64Tokens.add("I");
19 Base64Tokens.add("J");
20 Base64Tokens.add("K");
21 Base64Tokens.add("L");
22 Base64Tokens.add("M");
23 Base64Tokens.add("N");
24 Base64Tokens.add("O");
25 Base64Tokens.add("P");
26 Base64Tokens.add("Q");
27 Base64Tokens.add("R");
28 Base64Tokens.add("S");
29 Base64Tokens.add("T");
30 Base64Tokens.add("U");
31 Base64Tokens.add("V");
32 Base64Tokens.add("W");
33 Base64Tokens.add("X");
34 Base64Tokens.add("Y");
35 Base64Tokens.add("Z");
36 Base64Tokens.add("a");
37 Base64Tokens.add("b");
38 Base64Tokens.add("c");
39 Base64Tokens.add("d");
40 Base64Tokens.add("e");
41 Base64Tokens.add("f");
42 Base64Tokens.add("g");
43 Base64Tokens.add("h");
44 Base64Tokens.add("i");
45 Base64Tokens.add("j");
46 Base64Tokens.add("k");
47 Base64Tokens.add("l");
48 Base64Tokens.add("m");
49 Base64Tokens.add("n");
50 Base64Tokens.add("o");
51 Base64Tokens.add("p");
52 Base64Tokens.add("q");
53 Base64Tokens.add("r");
54 Base64Tokens.add("s");
55 Base64Tokens.add("t");
56 Base64Tokens.add("u");
57 Base64Tokens.add("v");
58 Base64Tokens.add("w");
59 Base64Tokens.add("x");
60 Base64Tokens.add("y");
61 Base64Tokens.add("z");
62 Base64Tokens.add("0");
63 Base64Tokens.add("1");
64 Base64Tokens.add("2");
65 Base64Tokens.add("3");
66 Base64Tokens.add("4");
67 Base64Tokens.add("5");
68 Base64Tokens.add("6");
69 Base64Tokens.add("7");
70 Base64Tokens.add("8");
71 Base64Tokens.add("9");
72 Base64Tokens.add("+");
73 Base64Tokens.add("/");
74 }
75 public static final char Base64Pad = '=';
76 public static final char Linefeed = (char)10;
77 public static final char Carriage = (char)13;
78 public static final int LineMax = 75;
79
80 public Base64Codec()
81 {
82 }
83
84 public static String encode(String source)
85 {
86 byte[] sourceBytes = source.getBytes();
87 int byteTriad = sourceBytes.length % 3;
88 StringBuffer encoding = new StringBuffer();
89 int bitOffset = 7;
90 int b64Offset = 5;
91 int bytePlace = 0;
92 byte tokenValue = (byte)0;
93 int lineLength = 0;
94 while(bytePlace < sourceBytes.length)
95 {
96 tokenValue = (byte)((byte)tokenValue | (byte)((sourceBytes[bytePlace] & (1 << bitOffset)) > 0 ? (1 << b64Offset) : (byte)0));
97 bitOffset--;
98 if(bitOffset < 0)
99 {
100 bitOffset = 7;
101 bytePlace++;
102 }
103 b64Offset--;
104 if(b64Offset < 0)
105 {
106 b64Offset = 5;
107 encoding.append((String)(Base64Tokens.elementAt(tokenValue)));
108 tokenValue = (byte)0;
109 lineLength++;
110 if(lineLength > LineMax)
111 {
112 encoding.append(Carriage);
113 encoding.append(Linefeed);
114 lineLength = 0;
115 }
116 }
117 }
118 if(b64Offset != 5)
119 {
120 bytePlace--;
121 for(int i = b64Offset; i >= 0; i--)
122 {
123 if(bitOffset >= 0)
124 {
125 tokenValue = (byte)((byte)tokenValue | (byte)((sourceBytes[bytePlace] & (1 << bitOffset)) > 0 ? (1 << i) : (byte)0));
126 }
127 bitOffset--;
128 }
129 encoding.append((String)(Base64Tokens.elementAt(tokenValue)));
130 }
131 if(byteTriad == 2)
132 {
133 encoding.append(Base64Pad);
134 }
135 else if(byteTriad == 1)
136 {
137 encoding.append(Base64Pad);
138 encoding.append(Base64Pad);
139 }
140 return encoding.toString();
141 }
142
143 public static String decode(String source)
144 {
145 StringBuffer decoding = new StringBuffer();
146 int bitOffset = 7;
147 int b64Offset = 5;
148 int bytePlace = 0;
149 byte charValue = (byte)0;
150 while(bytePlace < source.length())
151 {
152 if(source.charAt(bytePlace) == Base64Pad)
153 {
154 // end processing when encountering special end-padding character
155 break;
156 }
157 if(source.charAt(bytePlace) == Linefeed || source.charAt(bytePlace) == Carriage)
158 {
159 // ignore standard line break characters
160 bytePlace++;
161 continue;
162 }
163 else
164 {
165 if(!Base64Tokens.contains(source.substring(bytePlace, bytePlace + 1)))
166 {
167 // ignore unknown characters (mostly implemented to deal with other line break character sequences)
168 bytePlace++;
169 continue;
170 }
171 else
172 {
173 byte currentByte = (byte)(Base64Tokens.indexOf(source.substring(bytePlace, bytePlace + 1)));
174 charValue = (byte)((byte)charValue | (byte)((currentByte & (1 << b64Offset)) > 0 ? (1 << bitOffset) : (byte)0));
175 bitOffset--;
176 if(bitOffset < 0)
177 {
178 bitOffset = 7;
179 decoding.append((char)charValue);
180 charValue = (byte)0;
181 }
182 b64Offset--;
183 if(b64Offset < 0)
184 {
185 b64Offset = 5;
186 bytePlace++;
187 }
188 }
189 }
190 }
191 return decoding.toString();
192 }
193 }