1 19 20 package com.maverick.crypto.encoders; 21 22 import java.io.ByteArrayOutputStream ; 23 import java.io.IOException ; 24 import java.io.OutputStream ; 25 26 public class Base64 27 { 28 private static final byte[] encodingTable = 29 { 30 (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', 31 (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', 32 (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', 33 (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', 34 (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', 35 (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', 36 (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', 37 (byte)'v', 38 (byte)'w', (byte)'x', (byte)'y', (byte)'z', 39 (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', 40 (byte)'7', (byte)'8', (byte)'9', 41 (byte)'+', (byte)'/' 42 }; 43 44 49 public static byte[] encode( 50 byte[] data) 51 { 52 byte[] bytes; 53 54 int modulus = data.length % 3; 55 if (modulus == 0) 56 { 57 bytes = new byte[4 * data.length / 3]; 58 } 59 else 60 { 61 bytes = new byte[4 * ((data.length / 3) + 1)]; 62 } 63 64 int dataLength = (data.length - modulus); 65 int a1, a2, a3; 66 for (int i = 0, j = 0; i < dataLength; i += 3, j += 4) 67 { 68 a1 = data[i] & 0xff; 69 a2 = data[i + 1] & 0xff; 70 a3 = data[i + 2] & 0xff; 71 72 bytes[j] = encodingTable[(a1 >>> 2) & 0x3f]; 73 bytes[j + 1] = encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3f]; 74 bytes[j + 2] = encodingTable[((a2 << 2) | (a3 >>> 6)) & 0x3f]; 75 bytes[j + 3] = encodingTable[a3 & 0x3f]; 76 } 77 78 81 int b1, b2, b3; 82 int d1, d2; 83 84 switch (modulus) 85 { 86 case 0: 87 break; 88 case 1: 89 d1 = data[data.length - 1] & 0xff; 90 b1 = (d1 >>> 2) & 0x3f; 91 b2 = (d1 << 4) & 0x3f; 92 93 bytes[bytes.length - 4] = encodingTable[b1]; 94 bytes[bytes.length - 3] = encodingTable[b2]; 95 bytes[bytes.length - 2] = (byte)'='; 96 bytes[bytes.length - 1] = (byte)'='; 97 break; 98 case 2: 99 d1 = data[data.length - 2] & 0xff; 100 d2 = data[data.length - 1] & 0xff; 101 102 b1 = (d1 >>> 2) & 0x3f; 103 b2 = ((d1 << 4) | (d2 >>> 4)) & 0x3f; 104 b3 = (d2 << 2) & 0x3f; 105 106 bytes[bytes.length - 4] = encodingTable[b1]; 107 bytes[bytes.length - 3] = encodingTable[b2]; 108 bytes[bytes.length - 2] = encodingTable[b3]; 109 bytes[bytes.length - 1] = (byte)'='; 110 break; 111 } 112 113 return bytes; 114 } 115 116 119 private static final byte[] decodingTable; 120 121 static 122 { 123 decodingTable = new byte[128]; 124 125 for (int i = 'A'; i <= 'Z'; i++) 126 { 127 decodingTable[i] = (byte)(i - 'A'); 128 } 129 130 for (int i = 'a'; i <= 'z'; i++) 131 { 132 decodingTable[i] = (byte)(i - 'a' + 26); 133 } 134 135 for (int i = '0'; i <= '9'; i++) 136 { 137 decodingTable[i] = (byte)(i - '0' + 52); 138 } 139 140 decodingTable['+'] = 62; 141 decodingTable['/'] = 63; 142 } 143 144 149 public static byte[] decode( 150 byte[] data) 151 { 152 byte[] bytes; 153 byte b1, b2, b3, b4; 154 155 if (data[data.length - 2] == '=') 156 { 157 bytes = new byte[(((data.length / 4) - 1) * 3) + 1]; 158 } 159 else if (data[data.length - 1] == '=') 160 { 161 bytes = new byte[(((data.length / 4) - 1) * 3) + 2]; 162 } 163 else 164 { 165 bytes = new byte[((data.length / 4) * 3)]; 166 } 167 168 for (int i = 0, j = 0; i < data.length - 4; i += 4, j += 3) 169 { 170 b1 = decodingTable[data[i]]; 171 b2 = decodingTable[data[i + 1]]; 172 b3 = decodingTable[data[i + 2]]; 173 b4 = decodingTable[data[i + 3]]; 174 175 bytes[j] = (byte)((b1 << 2) | (b2 >> 4)); 176 bytes[j + 1] = (byte)((b2 << 4) | (b3 >> 2)); 177 bytes[j + 2] = (byte)((b3 << 6) | b4); 178 } 179 180 if (data[data.length - 2] == '=') 181 { 182 b1 = decodingTable[data[data.length - 4]]; 183 b2 = decodingTable[data[data.length - 3]]; 184 185 bytes[bytes.length - 1] = (byte)((b1 << 2) | (b2 >> 4)); 186 } 187 else if (data[data.length - 1] == '=') 188 { 189 b1 = decodingTable[data[data.length - 4]]; 190 b2 = decodingTable[data[data.length - 3]]; 191 b3 = decodingTable[data[data.length - 2]]; 192 193 bytes[bytes.length - 2] = (byte)((b1 << 2) | (b2 >> 4)); 194 bytes[bytes.length - 1] = (byte)((b2 << 4) | (b3 >> 2)); 195 } 196 else 197 { 198 b1 = decodingTable[data[data.length - 4]]; 199 b2 = decodingTable[data[data.length - 3]]; 200 b3 = decodingTable[data[data.length - 2]]; 201 b4 = decodingTable[data[data.length - 1]]; 202 203 bytes[bytes.length - 3] = (byte)((b1 << 2) | (b2 >> 4)); 204 bytes[bytes.length - 2] = (byte)((b2 << 4) | (b3 >> 2)); 205 bytes[bytes.length - 1] = (byte)((b3 << 6) | b4); 206 } 207 208 return bytes; 209 } 210 211 private static boolean ignore( 212 char c) 213 { 214 return (c == '\n' || c =='\r' || c == '\t' || c == ' '); 215 } 216 217 222 public static byte[] decode( 223 String data) 224 { 225 ByteArrayOutputStream bOut = new ByteArrayOutputStream (); 226 227 try 228 { 229 decode(data, bOut); 230 } 231 catch (IOException e) 232 { 233 throw new RuntimeException ("exception decoding base64 string: " + e); 234 } 235 236 return bOut.toByteArray(); 237 } 238 239 245 public static int decode( 246 String data, 247 OutputStream out) 248 throws IOException 249 { 250 byte[] bytes; 251 byte b1, b2, b3, b4; 252 int length = 0; 253 254 int end = data.length(); 255 256 while (end > 0) 257 { 258 if (!ignore(data.charAt(end - 1))) 259 { 260 break; 261 } 262 263 end--; 264 } 265 266 for (int i = 0; i < end - 4; i += 4) 267 { 268 if (ignore(data.charAt(i))) 269 { 270 continue; 271 } 272 273 b1 = decodingTable[data.charAt(i)]; 274 b2 = decodingTable[data.charAt(i + 1)]; 275 b3 = decodingTable[data.charAt(i + 2)]; 276 b4 = decodingTable[data.charAt(i + 3)]; 277 278 out.write((b1 << 2) | (b2 >> 4)); 279 out.write((b2 << 4) | (b3 >> 2)); 280 out.write((b3 << 6) | b4); 281 282 length += 3; 283 } 284 285 if (data.charAt(end - 2) == '=') 286 { 287 b1 = decodingTable[data.charAt(end - 4)]; 288 b2 = decodingTable[data.charAt(end - 3)]; 289 290 out.write((b1 << 2) | (b2 >> 4)); 291 292 length += 1; 293 } 294 else if (data.charAt(end - 1) == '=') 295 { 296 b1 = decodingTable[data.charAt(end - 4)]; 297 b2 = decodingTable[data.charAt(end - 3)]; 298 b3 = decodingTable[data.charAt(end - 2)]; 299 300 out.write((b1 << 2) | (b2 >> 4)); 301 out.write((b2 << 4) | (b3 >> 2)); 302 303 length += 2; 304 } 305 else 306 { 307 b1 = decodingTable[data.charAt(end - 4)]; 308 b2 = decodingTable[data.charAt(end - 3)]; 309 b3 = decodingTable[data.charAt(end - 2)]; 310 b4 = decodingTable[data.charAt(end - 1)]; 311 312 out.write((b1 << 2) | (b2 >> 4)); 313 out.write((b2 << 4) | (b3 >> 2)); 314 out.write((b3 << 6) | b4); 315 316 length += 3; 317 } 318 319 return length; 320 } 321 } 322 | Popular Tags |