1 29 30 package com.caucho.util; 31 32 import java.io.*; 33 34 37 public class Base64 { 38 static int decode[]; 39 40 static { 41 decode = new int[256]; 42 for (int i = 'A'; i <= 'Z'; i++) 43 decode[i] = i - 'A'; 44 for (int i = 'a'; i <= 'z'; i++) 45 decode[i] = i - 'a' + 26; 46 for (int i = '0'; i <= '9'; i++) 47 decode[i] = i - '0' + 52; 48 decode['+'] = 62; 49 decode['/'] = 63; 50 51 decode['='] = 0; 52 } 53 54 public static void encode(CharBuffer cb, long data) 55 { 56 cb.append(Base64.encode(data >> 60)); 57 cb.append(Base64.encode(data >> 54)); 58 cb.append(Base64.encode(data >> 48)); 59 cb.append(Base64.encode(data >> 42)); 60 cb.append(Base64.encode(data >> 36)); 61 cb.append(Base64.encode(data >> 30)); 62 cb.append(Base64.encode(data >> 24)); 63 cb.append(Base64.encode(data >> 18)); 64 cb.append(Base64.encode(data >> 12)); 65 cb.append(Base64.encode(data >> 6)); 66 cb.append(Base64.encode(data)); 67 } 68 69 public static void encode24(CharBuffer cb, int data) 70 { 71 cb.append(Base64.encode(data >> 18)); 72 cb.append(Base64.encode(data >> 12)); 73 cb.append(Base64.encode(data >> 6)); 74 cb.append(Base64.encode(data)); 75 } 76 77 public static void encode(CharBuffer cb, byte []buffer, 78 int offset, int length) 79 { 80 while (length >= 3) { 81 int data = (buffer[offset] & 0xff) << 16; 82 data += (buffer[offset + 1] & 0xff) << 8; 83 data += (buffer[offset + 2] & 0xff); 84 85 cb.append(Base64.encode(data >> 18)); 86 cb.append(Base64.encode(data >> 12)); 87 cb.append(Base64.encode(data >> 6)); 88 cb.append(Base64.encode(data)); 89 90 offset += 3; 91 length -= 3; 92 } 93 94 if (length == 2) { 95 int b1 = buffer[offset] & 0xff; 96 int b2 = buffer[offset + 1] & 0xff; 97 98 int data = (b1 << 16) + (b2 << 8); 99 100 cb.append(Base64.encode(data >> 18)); 101 cb.append(Base64.encode(data >> 12)); 102 cb.append(Base64.encode(data >> 6)); 103 cb.append('='); 104 } 105 else if (length == 1) { 106 int data = (buffer[offset] & 0xff) << 16; 107 108 cb.append(Base64.encode(data >> 18)); 109 cb.append(Base64.encode(data >> 12)); 110 cb.append('='); 111 cb.append('='); 112 } 113 } 114 115 public static void oldEncode(CharBuffer cb, byte []buffer, 116 int offset, int length) 117 { 118 while (length >= 3) { 119 int data = (buffer[offset] & 0xff) << 16; 120 data += (buffer[offset + 1] & 0xff) << 8; 121 data += (buffer[offset + 2] & 0xff); 122 123 cb.append(Base64.encode(data >> 18)); 124 cb.append(Base64.encode(data >> 12)); 125 cb.append(Base64.encode(data >> 6)); 126 cb.append(Base64.encode(data)); 127 128 offset += 3; 129 length -= 3; 130 } 131 132 if (length == 2) { 133 int b1 = buffer[offset] & 0xff; 134 int b2 = buffer[offset + 1] & 0xff; 135 136 int data = (b1 << 8) + (b2); 137 138 cb.append(Base64.encode(data >> 12)); 139 cb.append(Base64.encode(data >> 6)); 140 cb.append(Base64.encode(data)); 141 cb.append('='); 142 } 143 else if (length == 1) { 144 int data = (buffer[offset] & 0xff); 145 146 cb.append(Base64.encode(data >> 6)); 147 cb.append(Base64.encode(data)); 148 cb.append('='); 149 cb.append('='); 150 } 151 } 152 153 public static char encode(long d) 154 { 155 d &= 0x3f; 156 if (d < 26) 157 return (char) (d + 'A'); 158 else if (d < 52) 159 return (char) (d + 'a' - 26); 160 else if (d < 62) 161 return (char) (d + '0' - 52); 162 else if (d == 62) 163 return '+'; 164 else 165 return '/'; 166 } 167 168 public static int decode(int d) 169 { 170 return decode[d]; 171 } 172 173 public static String encode(String value) 174 { 175 try { 176 StringWriter sw = new StringWriter(); 177 encode(sw, new ByteArrayInputStream(value.getBytes())); 178 return sw.toString(); 179 } 180 catch (IOException e) { 181 throw new RuntimeException ("this should not be possible: " + e); 182 } 183 } 184 185 public static String encodeFromByteArray(byte[] value) 186 { 187 try { 188 StringWriter sw = new StringWriter(); 189 encode(sw, new ByteArrayInputStream(value)); 190 return sw.toString(); 191 } 192 catch (IOException e) { 193 throw new RuntimeException ("this should not be possible " + e); 194 } 195 } 196 197 public static String encodeFromByteArray(byte[] value, 198 int offset, 199 int length) 200 { 201 try { 202 StringWriter sw = new StringWriter(); 203 encode(sw, new ByteArrayInputStream(value, offset, length)); 204 return sw.toString(); 205 } 206 catch (IOException e) { 207 throw new RuntimeException ("this should not be possible " + e); 208 } 209 } 210 211 public static void encode(Writer w, InputStream i) 212 throws IOException 213 { 214 while(true) { 215 int value1 = i.read(); 216 int value2 = i.read(); 217 int value3 = i.read(); 218 219 if (value3 >= 0) { 220 long chunk = (value1 & 0xff); 221 chunk = (chunk << 8) + (value2 & 0xff); 222 chunk = (chunk << 8) + (value3 & 0xff); 223 224 w.write(encode(chunk >> 18)); 225 w.write(encode(chunk >> 12)); 226 w.write(encode(chunk >> 6)); 227 w.write(encode(chunk)); 228 continue; 229 } 230 231 if (value2 >= 0) { 232 long chunk = (value1 & 0xff); 233 chunk = (chunk << 8) + (value2 & 0xff); 234 chunk <<= 8; 235 236 w.write(encode(chunk >> 18)); 237 w.write(encode(chunk >> 12)); 238 w.write(encode(chunk >> 6)); 239 w.write('='); 240 } 241 else if (value1 >= 0) { 242 long chunk = (value1 & 0xff); 243 chunk <<= 16; 244 245 w.write(encode(chunk >> 18)); 246 w.write(encode(chunk >> 12)); 247 w.write('='); 248 w.write('='); 249 } 250 break; 251 } 252 w.flush(); 253 } 254 255 public static String decode(String value) 256 { 257 try { 258 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 259 decode(new StringReader(value), baos); 260 return new String (baos.toByteArray()); 261 } 262 catch (IOException e) { 263 throw new RuntimeException ("this should not be possible: " + e); 264 } 265 } 266 267 public static byte[] decodeToByteArray(String value) 268 { 269 try { 270 if (value == null) 271 return new byte[0]; 272 273 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 274 decode(new StringReader(value), baos); 275 return baos.toByteArray(); 276 } 277 catch (IOException e) { 278 throw new RuntimeException ("this should not be possible: " + e); 279 } 280 } 281 282 public static String oldDecode(String value) 283 { 284 CharBuffer cb = new CharBuffer(); 285 286 int length = value.length(); 287 for (int i = 0; i + 3 < length; i += 4) { 288 int ch0 = value.charAt(i + 0) & 0xff; 289 290 if (ch0 == ' ' || ch0 == '\n' || ch0 == '\r') { 292 i -= 3; 293 continue; 294 } 295 296 int ch1 = value.charAt(i + 1) & 0xff; 297 int ch2 = value.charAt(i + 2) & 0xff; 298 int ch3 = value.charAt(i + 3) & 0xff; 299 300 int chunk = ((decode[ch0] << 18) + 301 (decode[ch1] << 12) + 302 (decode[ch2] << 6) + 303 (decode[ch3])); 304 305 cb.append((char) ((chunk >> 16) & 0xff)); 306 307 if (ch2 != '=') 308 cb.append((char) ((chunk >> 8) & 0xff)); 309 if (ch3 != '=') 310 cb.append((char) ((chunk & 0xff))); 311 } 312 313 return cb.toString(); 314 } 315 316 private static int readNonWhitespace(Reader r) 317 throws IOException 318 { 319 while(true) { 320 int ret = r.read(); 321 if (ret == ' ' || ret == '\n' || ret == '\r') 323 continue; 324 return ret; 325 } 326 } 327 328 public static void decode(Reader r, OutputStream os) 329 throws IOException 330 { 331 while(true) { 332 int ch0 = readNonWhitespace(r); 333 int ch1 = r.read(); 334 int ch2 = r.read(); 335 int ch3 = r.read(); 336 337 if (ch1 < 0) 338 break; 339 if (ch2 < 0) 340 ch2 = '='; 341 if (ch3 < 0) 342 ch3 = '='; 343 344 int chunk = ((decode[ch0] << 18) + 345 (decode[ch1] << 12) + 346 (decode[ch2] << 6) + 347 (decode[ch3])); 348 349 os.write((byte) ((chunk >> 16) & 0xff)); 350 351 if (ch2 != '=' && ch2 != -1) 352 os.write((byte) ((chunk >> 8) & 0xff)); 353 if (ch3 != '=' && ch3 != -1) 354 os.write((byte) ((chunk & 0xff))); 355 else 356 break; 357 } 358 os.flush(); 359 } 360 } 361 | Popular Tags |