1 19 20 package com.maverick.util; 21 22 23 28 public class Base64 { 29 30 public final static boolean ENCODE = true; 31 32 33 public final static boolean DECODE = false; 34 private final static int MAX_LINE_LENGTH = 76; 35 private final static byte EQUALS_SIGN = (byte) '='; 36 private final static byte NEW_LINE = (byte) '\n'; 37 private final static byte[] ALPHABET = { 38 (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', 39 (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', 40 (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', 41 (byte) 'S', (byte) 'T', (byte) 'U', (byte) 'V', (byte) 'W', (byte) 'X', 42 (byte) 'Y', (byte) 'Z', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', 43 (byte) 'e', (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', 44 (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o', (byte) 'p', 45 (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u', (byte) 'v', 46 (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z', (byte) '0', (byte) '1', 47 (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7', 48 (byte) '8', (byte) '9', (byte) '+', (byte) '/' 49 }; 50 private final static byte[] DECODABET = { 51 -9, -9, -9, -9, -9, -9, -9, -9, -9, -5, -5, -9, -9, -5, -9, -9, -9, -9, 52 -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -5, -9, -9, -9, 53 -9, -9, -9, -9, -9, -9, -9, 54 62, -9, -9, -9, 56 63, 58 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -9, -9, -9, -1, -9, -9, -9, 60 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 62 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -9, -9, -9, -9, -9, -9, 64 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 66 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -9, -9, -9, -9 68 }; 69 private final static byte BAD_ENCODING = -9; 70 71 private final static byte white_SPACE_ENC = -5; 73 74 private final static byte EQUALS_SIGN_ENC = -1; 76 77 private Base64() { 79 } 80 81 88 public static byte[] decode(String s) { 89 byte[] bytes = s.getBytes(); 90 91 return decode(bytes, 0, bytes.length); 92 } 93 94 public static byte[] decode(byte[] source, int off, int len) { 96 int len34 = (len * 3) / 4; 97 byte[] outBuff = new byte[len34]; 98 99 int outBuffPosn = 0; 101 102 byte[] b4 = new byte[4]; 103 int b4Posn = 0; 104 int i = 0; 105 byte sbiCrop = 0; 106 byte sbiDecode = 0; 107 108 for (i = off; i < len; i++) { 109 sbiCrop = (byte) (source[i] & 0x7f); 110 111 sbiDecode = DECODABET[sbiCrop]; 113 114 if (sbiDecode >= white_SPACE_ENC) { 115 if (sbiDecode >= EQUALS_SIGN_ENC) { 117 b4[b4Posn++] = sbiCrop; 118 119 if (b4Posn > 3) { 120 outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn); 121 b4Posn = 0; 122 123 if (sbiCrop == EQUALS_SIGN) { 125 break; 126 } 127 } 128 129 } 131 132 } 134 else { 136 System.err.println("Bad Base64 input character at " + i + ": " 137 + source[i] + "(decimal)"); 138 139 return null; 140 } 141 142 } 144 145 byte[] out = new byte[outBuffPosn]; 147 System.arraycopy(outBuff, 0, out, 0, outBuffPosn); 148 149 return out; 150 } 151 152 public static Object decodeToObject(String encodedObject) { 154 byte[] objBytes = decode(encodedObject); 155 156 java.io.ByteArrayInputStream bais = null; 157 java.io.ObjectInputStream ois = null; 158 159 try { 160 bais = new java.io.ByteArrayInputStream (objBytes); 161 ois = new java.io.ObjectInputStream (bais); 162 163 return ois.readObject(); 164 } 165 catch (java.io.IOException e) { 167 return null; 168 } 169 catch (java.lang.ClassNotFoundException e) { 171 return null; 172 } 173 finally { 175 try { 176 bais.close(); 177 } 178 catch (Exception e) { 179 } 180 181 try { 182 ois.close(); 183 } 184 catch (Exception e) { 185 } 186 } 187 188 } 190 191 public static String decodeToString(String s) { 193 return new String (decode(s)); 194 } 195 196 public static String encodeBytes(byte[] source, boolean ignoreMaxLineLength) { 198 return encodeBytes(source, 0, source.length, ignoreMaxLineLength); 199 } 200 201 public static String encodeBytes(byte[] source, int off, int len, 203 boolean ignoreMaxLineLength) { 204 int len43 = (len * 4) / 3; 205 byte[] outBuff = new byte[ (len43) + ( ( (len % 3) > 0) ? 4 : 0) 206 + (len43 / MAX_LINE_LENGTH)]; 207 208 int d = 0; 210 int e = 0; 211 int len2 = len - 2; 212 int lineLength = 0; 213 214 for (; d < len2; d += 3, e += 4) { 215 encode3to4(source, d + off, 3, outBuff, e); 216 217 lineLength += 4; 218 219 if (!ignoreMaxLineLength) { 220 if (lineLength == MAX_LINE_LENGTH) { 221 outBuff[e + 4] = NEW_LINE; 222 e++; 223 lineLength = 0; 224 } 225 226 } 228 } 229 230 if (d < len) { 232 encode3to4(source, d + off, len - d, outBuff, e); 233 e += 4; 234 } 235 236 return new String (outBuff, 0, e); 238 } 239 240 public static String encodeObject(java.io.Serializable serializableObject) { 242 java.io.ByteArrayOutputStream baos = null; 243 java.io.OutputStream b64os = null; 244 java.io.ObjectOutputStream oos = null; 245 246 try { 247 baos = new java.io.ByteArrayOutputStream (); 248 b64os = new Base64.OutputStream(baos, Base64.ENCODE); 249 oos = new java.io.ObjectOutputStream (b64os); 250 251 oos.writeObject(serializableObject); 252 } 253 catch (java.io.IOException e) { 255 return null; 256 } 257 finally { 259 try { 260 oos.close(); 261 } 262 catch (Exception e) { 263 } 264 265 try { 266 b64os.close(); 267 } 268 catch (Exception e) { 269 } 270 271 try { 272 baos.close(); 273 } 274 catch (Exception e) { 275 } 276 } 277 278 return new String (baos.toByteArray()); 280 } 281 282 public static String encodeString(String s, boolean ignoreMaxLineLength) { 284 return encodeBytes(s.getBytes(), ignoreMaxLineLength); 285 } 286 287 336 337 340 private static byte[] decode4to3(byte[] fourBytes) { 341 byte[] outBuff1 = new byte[3]; 342 int count = decode4to3(fourBytes, 0, outBuff1, 0); 343 byte[] outBuff2 = new byte[count]; 344 345 for (int i = 0; i < count; i++) { 346 outBuff2[i] = outBuff1[i]; 347 } 348 349 return outBuff2; 350 } 351 352 private static int decode4to3(byte[] source, int srcOffset, 353 byte[] destination, int destOffset) { 354 if (source[srcOffset + 2] == EQUALS_SIGN) { 356 int outBuff = ( (DECODABET[source[srcOffset]] << 24) >>> 6) 357 | ( (DECODABET[source[srcOffset + 1]] << 24) >>> 12); 358 359 destination[destOffset] = (byte) (outBuff >>> 16); 360 361 return 1; 362 } 363 else if (source[srcOffset + 3] == EQUALS_SIGN) { 365 int outBuff = ( (DECODABET[source[srcOffset]] << 24) >>> 6) 366 | ( (DECODABET[source[srcOffset + 1]] << 24) >>> 12) 367 | ( (DECODABET[source[srcOffset + 2]] << 24) >>> 18); 368 369 destination[destOffset] = (byte) (outBuff >>> 16); 370 destination[destOffset + 1] = (byte) (outBuff >>> 8); 371 372 return 2; 373 } 374 else { 376 int outBuff = ( (DECODABET[source[srcOffset]] << 24) >>> 6) 377 | ( (DECODABET[source[srcOffset + 1]] << 24) >>> 12) 378 | ( (DECODABET[source[srcOffset + 2]] << 24) >>> 18) 379 | ( (DECODABET[source[srcOffset + 3]] << 24) >>> 24); 380 381 destination[destOffset] = (byte) (outBuff >> 16); 382 destination[destOffset + 1] = (byte) (outBuff >> 8); 383 destination[destOffset + 2] = (byte) (outBuff); 384 385 return 3; 386 } 387 } 388 389 391 394 private static byte[] encode3to4(byte[] threeBytes) { 395 return encode3to4(threeBytes, 3); 396 } 397 398 private static byte[] encode3to4(byte[] threeBytes, int numSigBytes) { 400 byte[] dest = new byte[4]; 401 encode3to4(threeBytes, 0, numSigBytes, dest, 0); 402 403 return dest; 404 } 405 406 private static byte[] encode3to4(byte[] source, int srcOffset, 407 int numSigBytes, byte[] destination, 408 int destOffset) { 409 int inBuff = ( (numSigBytes > 0) ? ( (source[srcOffset] << 24) >>> 8) : 0) 420 | ( (numSigBytes > 1) ? ( (source[srcOffset + 1] << 24) >>> 16) : 0) 421 | ( (numSigBytes > 2) ? ( (source[srcOffset + 2] << 24) >>> 24) : 0); 422 423 switch (numSigBytes) { 424 case 3: 425 destination[destOffset] = ALPHABET[ (inBuff >>> 18)]; 426 destination[destOffset + 1] = ALPHABET[ (inBuff >>> 12) & 0x3f]; 427 destination[destOffset + 2] = ALPHABET[ (inBuff >>> 6) & 0x3f]; 428 destination[destOffset + 3] = ALPHABET[ (inBuff) & 0x3f]; 429 430 return destination; 431 432 case 2: 433 destination[destOffset] = ALPHABET[ (inBuff >>> 18)]; 434 destination[destOffset + 1] = ALPHABET[ (inBuff >>> 12) & 0x3f]; 435 destination[destOffset + 2] = ALPHABET[ (inBuff >>> 6) & 0x3f]; 436 destination[destOffset + 3] = EQUALS_SIGN; 437 438 return destination; 439 440 case 1: 441 destination[destOffset] = ALPHABET[ (inBuff >>> 18)]; 442 destination[destOffset + 1] = ALPHABET[ (inBuff >>> 12) & 0x3f]; 443 destination[destOffset + 2] = EQUALS_SIGN; 444 destination[destOffset + 3] = EQUALS_SIGN; 445 446 return destination; 447 448 default: 449 return destination; 450 } 451 452 } 454 455 457 460 public static class InputStream 461 extends java.io.FilterInputStream { 462 private byte[] buffer; 463 464 private boolean encode; 466 467 private int bufferLength; 469 470 private int numSigBytes; 472 473 private int position; 475 476 public InputStream(java.io.InputStream in) { 478 this(in, Base64.DECODE); 479 } 480 481 public InputStream(java.io.InputStream in, boolean encode) { 483 super(in); 484 this.encode = encode; 485 this.bufferLength = encode ? 4 : 3; 486 this.buffer = new byte[bufferLength]; 487 this.position = -1; 488 } 489 490 public int read() throws java.io.IOException { 492 if (position < 0) { 494 if (encode) { 495 byte[] b3 = new byte[3]; 496 numSigBytes = 0; 497 498 for (int i = 0; i < 3; i++) { 499 try { 500 int b = in.read(); 501 502 if (b >= 0) { 504 b3[i] = (byte) b; 505 numSigBytes++; 506 } 507 508 } 510 catch (java.io.IOException e) { 512 if (i == 0) { 514 throw e; 515 } 516 } 517 518 } 520 521 if (numSigBytes > 0) { 523 encode3to4(b3, 0, numSigBytes, buffer, 0); 524 position = 0; 525 } 526 527 } 529 else { 532 byte[] b4 = new byte[4]; 533 int i = 0; 534 535 for (i = 0; i < 4; i++) { 536 int b = 0; 537 538 do { 539 b = in.read(); 540 } 541 while ( (b >= 0) 542 && (DECODABET[b & 0x7f] < white_SPACE_ENC)); 543 544 if (b < 0) { 545 break; 546 547 } 549 550 b4[i] = (byte) b; 551 } 552 553 if (i == 4) { 555 numSigBytes = decode4to3(b4, 0, buffer, 0); 556 position = 0; 557 } 558 559 } 561 562 } 564 565 if (position >= 0) { 568 if (!encode && (position >= numSigBytes)) { 570 return -1; 571 } 572 573 int b = buffer[position++]; 574 575 if (position >= bufferLength) { 576 position = -1; 577 } 578 579 return b; 580 } 581 else { 584 return -1; 585 } 586 } 587 588 public int read(byte[] dest, int off, int len) throws java.io.IOException { 590 int i; 591 int b; 592 593 for (i = 0; i < len; i++) { 594 b = read(); 595 596 if (b < 0) { 597 return -1; 598 } 599 600 dest[off + i] = (byte) b; 601 } 602 603 return i; 605 } 606 607 } 609 610 612 615 public static class OutputStream 616 extends java.io.FilterOutputStream { 617 private byte[] buffer; 618 private boolean encode; 619 private int bufferLength; 620 private int lineLength; 621 private int position; 622 623 public OutputStream(java.io.OutputStream out) { 624 this(out, Base64.ENCODE); 625 } 626 627 public OutputStream(java.io.OutputStream out, boolean encode) { 629 super(out); 630 this.encode = encode; 631 this.bufferLength = encode ? 3 : 4; 632 this.buffer = new byte[bufferLength]; 633 this.position = 0; 634 this.lineLength = 0; 635 } 636 637 public void close() throws java.io.IOException { 639 this.flush(); 640 641 super.close(); 642 out.close(); 643 644 buffer = null; 645 out = null; 646 } 647 648 public void flush() throws java.io.IOException { 650 if (position > 0) { 651 if (encode) { 652 out.write(Base64.encode3to4(buffer, position)); 653 } 654 else { 656 throw new java.io.IOException ( 657 "Base64 input not properly padded."); 658 } 659 660 } 662 663 super.flush(); 665 out.flush(); 666 } 667 668 public void write(int theByte) throws java.io.IOException { 670 buffer[position++] = (byte) theByte; 671 672 if (position >= bufferLength) { 673 if (encode) { 674 out.write(Base64.encode3to4(buffer, bufferLength)); 675 676 lineLength += 4; 677 678 if (lineLength >= MAX_LINE_LENGTH) { 679 out.write(NEW_LINE); 680 lineLength = 0; 681 } 682 683 } 685 else { 687 out.write(Base64.decode4to3(buffer)); 688 } 689 690 position = 0; 691 } 692 693 } 695 696 public void write(byte[] theBytes, int off, int len) throws java.io. 698 IOException { 699 for (int i = 0; i < len; i++) { 700 write(theBytes[off + i]); 701 } 702 703 } 705 706 } 708 709 } 711 | Popular Tags |