1 20 21 package cowsultants.itracker.ejb.client.util; 22 23 public class Base64 { 24 25 public final static int NO_OPTIONS = 0; 26 27 public final static int ENCODE = 1; 28 29 public final static int DECODE = 0; 30 31 public final static int GZIP = 2; 32 33 public final static int DONT_BREAK_LINES = 8; 34 35 36 private final static int MAX_LINE_LENGTH = 76; 37 38 private final static byte EQUALS_SIGN = (byte)'='; 39 40 private final static byte NEW_LINE = (byte)'\n'; 41 42 private final static String PREFERRED_ENCODING = "UTF-8"; 43 44 45 46 private final static byte[] ALPHABET; 47 private final static byte[] _NATIVE_ALPHABET = { 48 (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', 49 (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', 50 (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', 51 (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', 52 (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', 53 (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', 54 (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', 55 (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z', 56 (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', 57 (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'+', (byte)'/' 58 }; 59 60 61 static { 62 byte[] __bytes; 63 try { 64 __bytes = new String ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/").getBytes( PREFERRED_ENCODING ); 65 } catch (java.io.UnsupportedEncodingException use) { 66 __bytes = _NATIVE_ALPHABET; 67 } 68 69 ALPHABET = __bytes; 70 } 71 72 73 77 private final static byte[] DECODABET = { 78 -9,-9,-9,-9,-9,-9,-9,-9,-9, -5,-5, -9,-9, -5, -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, -9,-9,-9,-9,-9, -5, -9,-9,-9,-9,-9,-9,-9,-9,-9,-9, 62, -9,-9,-9, 63, 52,53,54,55,56,57,58,59,60,61, -9,-9,-9, -1, -9,-9,-9, 0,1,2,3,4,5,6,7,8,9,10,11,12,13, 14,15,16,17,18,19,20,21,22,23,24,25, -9,-9,-9,-9,-9,-9, 26,27,28,29,30,31,32,33,34,35,36,37,38, 39,40,41,42,43,44,45,46,47,48,49,50,51, -9,-9,-9,-9 109 }; 110 111 private final static byte BAD_ENCODING = -9; private final static byte WHITE_SPACE_ENC = -5; private final static byte EQUALS_SIGN_ENC = -1; 115 116 117 private Base64() {} 118 119 126 private static byte[] encode3to4( byte[] threeBytes ) { 127 return encode3to4( threeBytes, 3 ); 128 } 129 130 131 132 144 private static byte[] encode3to4(byte[] threeBytes, int numSigBytes) { 145 byte[] dest = new byte[4]; 146 encode3to4( threeBytes, 0, numSigBytes, dest, 0 ); 147 return dest; 148 } 149 150 164 private static byte[] encode3to4(byte[] b4, byte[] threeBytes, int numSigBytes) { 165 encode3to4( threeBytes, 0, numSigBytes, b4, 0 ); 166 return b4; 167 } 168 169 189 private static byte[] encode3to4(byte[] source, int srcOffset, int numSigBytes, byte[] destination, int destOffset) { 190 197 int inBuff = ( numSigBytes > 0 ? ((source[ srcOffset ] << 24) >>> 8) : 0 ) 202 | ( numSigBytes > 1 ? ((source[ srcOffset + 1 ] << 24) >>> 16) : 0 ) 203 | ( numSigBytes > 2 ? ((source[ srcOffset + 2 ] << 24) >>> 24) : 0 ); 204 205 switch( numSigBytes ) { 206 case 3: 207 destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; 208 destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; 209 destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>> 6) & 0x3f ]; 210 destination[ destOffset + 3 ] = ALPHABET[ (inBuff ) & 0x3f ]; 211 return destination; 212 213 case 2: 214 destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; 215 destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; 216 destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>> 6) & 0x3f ]; 217 destination[ destOffset + 3 ] = EQUALS_SIGN; 218 return destination; 219 220 case 1: 221 destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; 222 destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; 223 destination[ destOffset + 2 ] = EQUALS_SIGN; 224 destination[ destOffset + 3 ] = EQUALS_SIGN; 225 return destination; 226 227 default: 228 return destination; 229 } 230 } 231 232 242 public static String encodeObject(java.io.Serializable serializableObject) { 243 return encodeObject( serializableObject, NO_OPTIONS ); 244 } 245 246 268 public static String encodeObject(java.io.Serializable serializableObject, int options) { 269 java.io.ByteArrayOutputStream baos = null; 270 java.io.OutputStream b64os = null; 271 java.io.ObjectOutputStream oos = null; 272 java.util.zip.GZIPOutputStream gzos = null; 273 274 int gzip = (options & GZIP); 275 int dontBreakLines = (options & DONT_BREAK_LINES); 276 277 try { 278 baos = new java.io.ByteArrayOutputStream (); 280 b64os = new Base64.OutputStream( baos, ENCODE | dontBreakLines ); 281 282 if(gzip == GZIP) { 284 gzos = new java.util.zip.GZIPOutputStream ( b64os ); 285 oos = new java.io.ObjectOutputStream ( gzos ); 286 } else { 287 oos = new java.io.ObjectOutputStream ( b64os ); 288 } 289 290 oos.writeObject( serializableObject ); 291 } catch( java.io.IOException e ) { 292 e.printStackTrace(); 293 return null; 294 } finally { 295 try{ oos.close(); } catch( Exception e ){} 296 try{ gzos.close(); } catch( Exception e ){} 297 try{ b64os.close(); } catch( Exception e ){} 298 try{ baos.close(); } catch( Exception e ){} 299 } 300 301 try { 303 return new String ( baos.toByteArray(), PREFERRED_ENCODING ); 304 } catch (java.io.UnsupportedEncodingException uue) { 305 return new String ( baos.toByteArray() ); 306 } 307 } 308 309 315 public static String encodeBytes(byte[] source) { 316 return encodeBytes(source, 0, source.length, NO_OPTIONS); 317 } 318 319 338 public static String encodeBytes(byte[] source, int options) { 339 return encodeBytes(source, 0, source.length, options); 340 } 341 342 350 public static String encodeBytes( byte[] source, int off, int len) { 351 return encodeBytes( source, off, len, NO_OPTIONS ); 352 } 353 354 376 public static String encodeBytes( byte[] source, int off, int len, int options) { 377 int dontBreakLines = ( options & DONT_BREAK_LINES ); 379 int gzip = ( options & GZIP ); 380 381 if(gzip == GZIP) { 383 java.io.ByteArrayOutputStream baos = null; 384 java.util.zip.GZIPOutputStream gzos = null; 385 Base64.OutputStream b64os = null; 386 387 try { 388 baos = new java.io.ByteArrayOutputStream (); 390 b64os = new Base64.OutputStream( baos, ENCODE | dontBreakLines ); 391 gzos = new java.util.zip.GZIPOutputStream ( b64os ); 392 393 gzos.write( source, off, len ); 394 gzos.close(); 395 } catch( java.io.IOException e ) { 396 e.printStackTrace(); 397 return null; 398 } finally { 399 try{ gzos.close(); } catch( Exception e ){} 400 try{ b64os.close(); } catch( Exception e ){} 401 try{ baos.close(); } catch( Exception e ){} 402 } 403 404 try { 406 return new String ( baos.toByteArray(), PREFERRED_ENCODING ); 407 } catch(java.io.UnsupportedEncodingException uue) { 408 return new String ( baos.toByteArray() ); 409 } 410 } else { 411 boolean breakLines = dontBreakLines == 0; 413 414 int len43 = len * 4 / 3; 415 byte[] outBuff = new byte[ ( len43 ) + ( (len % 3) > 0 ? 4 : 0 ) + (breakLines ? ( len43 / MAX_LINE_LENGTH ) : 0) ]; int d = 0; 419 int e = 0; 420 int len2 = len - 2; 421 int lineLength = 0; 422 for( ; d < len2; d+=3, e+=4 ) { 423 encode3to4( source, d+off, 3, outBuff, e ); 424 425 lineLength += 4; 426 if( breakLines && lineLength == MAX_LINE_LENGTH ) { 427 outBuff[e+4] = NEW_LINE; 428 e++; 429 lineLength = 0; 430 } 431 } 432 433 if( d < len ) { 434 encode3to4( source, d+off, len - d, outBuff, e ); 435 e += 4; 436 } 437 438 try { 440 return new String ( outBuff, 0, e, PREFERRED_ENCODING ); 441 } catch (java.io.UnsupportedEncodingException uue) { 442 return new String ( outBuff, 0, e ); 443 } 444 } 445 } 446 447 455 private static byte[] decode4to3( byte[] fourBytes ) { 456 byte[] outBuff1 = new byte[3]; 457 int count = decode4to3( fourBytes, 0, outBuff1, 0 ); 458 byte[] outBuff2 = new byte[ count ]; 459 460 for( int i = 0; i < count; i++ ) 461 outBuff2[i] = outBuff1[i]; 462 463 return outBuff2; 464 } 465 466 487 private static int decode4to3( byte[] source, int srcOffset, byte[] destination, int destOffset ) { 488 if( source[ srcOffset + 2] == EQUALS_SIGN ) 490 { 491 int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) 495 | ( ( DECODABET[ source[ srcOffset + 1] ] & 0xFF ) << 12 ); 496 497 destination[ destOffset ] = (byte)( outBuff >>> 16 ); 498 return 1; 499 } else if( source[ srcOffset + 3 ] == EQUALS_SIGN ) { 500 int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) 505 | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 ) 506 | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) << 6 ); 507 508 destination[ destOffset ] = (byte)( outBuff >>> 16 ); 509 destination[ destOffset + 1 ] = (byte)( outBuff >>> 8 ); 510 return 2; 511 } else { 512 try { 513 int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) 519 | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 ) 520 | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) << 6) 521 | ( ( DECODABET[ source[ srcOffset + 3 ] ] & 0xFF ) ); 522 523 524 destination[ destOffset ] = (byte)( outBuff >> 16 ); 525 destination[ destOffset + 1 ] = (byte)( outBuff >> 8 ); 526 destination[ destOffset + 2 ] = (byte)( outBuff ); 527 528 return 3; 529 }catch( Exception e){ 530 System.out.println(""+source[srcOffset]+ ": " + ( DECODABET[ source[ srcOffset ] ] ) ); 531 System.out.println(""+source[srcOffset+1]+ ": " + ( DECODABET[ source[ srcOffset + 1 ] ] ) ); 532 System.out.println(""+source[srcOffset+2]+ ": " + ( DECODABET[ source[ srcOffset + 2 ] ] ) ); 533 System.out.println(""+source[srcOffset+3]+ ": " + ( DECODABET[ source[ srcOffset + 3 ] ] ) ); 534 return -1; 535 } 536 } 537 } 538 539 549 public static byte[] decode( byte[] source, int off, int len ) { 550 int len34 = len * 3 / 4; 551 byte[] outBuff = new byte[ len34 ]; int outBuffPosn = 0; 553 554 byte[] b4 = new byte[4]; 555 int b4Posn = 0; 556 int i = 0; 557 byte sbiCrop = 0; 558 byte sbiDecode = 0; 559 for( i = off; i < off+len; i++ ) 560 { 561 sbiCrop = (byte)(source[i] & 0x7f); sbiDecode = DECODABET[ sbiCrop ]; 563 564 if( sbiDecode >= WHITE_SPACE_ENC ) { 566 if( sbiDecode >= EQUALS_SIGN_ENC ) 567 { 568 b4[ b4Posn++ ] = sbiCrop; 569 if( b4Posn > 3 ) 570 { 571 outBuffPosn += decode4to3( b4, 0, outBuff, outBuffPosn ); 572 b4Posn = 0; 573 574 if( sbiCrop == EQUALS_SIGN ) 576 break; 577 } 579 } 581 } else { 582 System.err.println( "Bad Base64 input character at " + i + ": " + source[i] + "(decimal)" ); 583 return null; 584 } } 587 byte[] out = new byte[ outBuffPosn ]; 588 System.arraycopy( outBuff, 0, out, 0, outBuffPosn ); 589 return out; 590 } 591 592 599 public static byte[] decode( String s ) 600 { 601 byte[] bytes; 602 try { 603 bytes = s.getBytes( PREFERRED_ENCODING ); 604 } catch( java.io.UnsupportedEncodingException uee ) { 605 bytes = s.getBytes(); 606 } 607 608 bytes = decode( bytes, 0, bytes.length ); 610 611 if( bytes.length >= 2 ) 614 { 615 616 int head = ((int)bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00); 617 if( bytes != null && bytes.length >= 4 && java.util.zip.GZIPInputStream.GZIP_MAGIC == head) { 618 java.io.ByteArrayInputStream bais = null; 619 java.util.zip.GZIPInputStream gzis = null; 620 java.io.ByteArrayOutputStream baos = null; 621 byte[] buffer = new byte[2048]; 622 int length = 0; 623 624 try 625 { 626 baos = new java.io.ByteArrayOutputStream (); 627 bais = new java.io.ByteArrayInputStream ( bytes ); 628 gzis = new java.util.zip.GZIPInputStream ( bais ); 629 630 while( ( length = gzis.read( buffer ) ) >= 0 ) 631 { 632 baos.write(buffer,0,length); 633 } 635 bytes = baos.toByteArray(); 637 638 } catch( java.io.IOException e ) { 639 } finally { 640 try{ baos.close(); } catch( Exception e ){} 641 try{ gzis.close(); } catch( Exception e ){} 642 try{ bais.close(); } catch( Exception e ){} 643 } 644 } 645 } 646 647 return bytes; 648 } 649 650 651 652 659 public static Object decodeToObject( String encodedObject ) { 660 byte[] objBytes = decode( encodedObject ); 662 663 java.io.ByteArrayInputStream bais = null; 664 java.io.ObjectInputStream ois = null; 665 Object obj = null; 666 667 try 668 { 669 bais = new java.io.ByteArrayInputStream ( objBytes ); 670 ois = new java.io.ObjectInputStream ( bais ); 671 672 obj = ois.readObject(); 673 } catch( java.io.IOException e ) { 674 e.printStackTrace(); 675 obj = null; 676 } catch( java.lang.ClassNotFoundException e ) { 677 e.printStackTrace(); 678 obj = null; 679 } finally { 680 try{ bais.close(); } catch( Exception e ){} 681 try{ ois.close(); } catch( Exception e ){} 682 } 683 684 return obj; 685 } 686 687 695 public static class InputStream extends java.io.FilterInputStream 696 { 697 private int options; private boolean encode; private int position; private byte[] buffer; private int bufferLength; private int numSigBytes; private int lineLength; 704 private boolean breakLines; 706 707 712 public InputStream( java.io.InputStream in ) 713 { 714 this( in, DECODE ); 715 } 716 717 718 738 public InputStream( java.io.InputStream in, int options ) 739 { 740 super( in ); 741 this.options = options; 742 this.breakLines = (options & DONT_BREAK_LINES) != DONT_BREAK_LINES; 743 this.encode = (options & ENCODE) == ENCODE; 744 this.breakLines = breakLines; 745 this.encode = encode; 746 this.bufferLength = encode ? 4 : 3; 747 this.buffer = new byte[ bufferLength ]; 748 this.position = -1; 749 this.lineLength = 0; 750 } 751 752 758 public int read() throws java.io.IOException { 759 if( position < 0 ) { 761 if( encode ) { 762 byte[] b3 = new byte[3]; 763 int numBinaryBytes = 0; 764 for( int i = 0; i < 3; i++ ) { 765 try { 766 int b = in.read(); 767 768 if( b >= 0 ) { 770 b3[i] = (byte)b; 771 numBinaryBytes++; 772 } 773 } catch( java.io.IOException e ) { 774 if( i == 0 ) 776 throw e; 777 778 } 779 } 780 781 if( numBinaryBytes > 0 ) 782 { 783 encode3to4( b3, 0, numBinaryBytes, buffer, 0 ); 784 position = 0; 785 numSigBytes = 4; 786 } else { 787 return -1; 788 } 789 } else { 790 byte[] b4 = new byte[4]; 791 int i = 0; 792 for( i = 0; i < 4; i++ ) 793 { 794 int b = 0; 796 do{ b = in.read(); } 797 while( b >= 0 && DECODABET[ b & 0x7f ] <= WHITE_SPACE_ENC ); 798 799 if( b < 0 ) 800 break; 802 b4[i] = (byte)b; 803 } 805 if( i == 4 ) 806 { 807 numSigBytes = decode4to3( b4, 0, buffer, 0 ); 808 position = 0; 809 } else if( i == 0 ) { 810 return -1; 811 } else { 812 throw new java.io.IOException ( "Improperly padded Base64 input." ); 814 } 815 } 816 } 817 818 if( position >= 0 ) { 820 if( position >= numSigBytes ) 822 return -1; 823 824 if( encode && breakLines && lineLength >= MAX_LINE_LENGTH ) { 825 lineLength = 0; 826 return '\n'; 827 } else { 828 lineLength++; 832 int b = buffer[ position++ ]; 833 834 if( position >= bufferLength ) 835 position = -1; 836 837 return b & 0xFF; } } else { 841 throw new java.io.IOException ( "Error in Base64 code reading stream." ); 843 } } 846 847 858 public int read( byte[] dest, int off, int len ) throws java.io.IOException 859 { 860 int i; 861 int b; 862 for( i = 0; i < len; i++ ) 863 { 864 b = read(); 865 866 869 if( b >= 0 ) 870 dest[off + i] = (byte)b; 871 else if( i == 0 ) 872 return -1; 873 else 874 break; } return i; 877 } 879 } 881 882 890 public static class OutputStream extends java.io.FilterOutputStream { 891 private int options; 892 private boolean encode; 893 private int position; 894 private byte[] buffer; 895 private int bufferLength; 896 private int lineLength; 897 private boolean breakLines; 898 private byte[] b4; private boolean suspendEncoding; 900 901 907 public OutputStream( java.io.OutputStream out ) 908 { 909 this( out, ENCODE ); 910 } 912 913 932 public OutputStream( java.io.OutputStream out, int options ) 933 { 934 super( out ); 935 this.options = options; 936 this.breakLines = (options & DONT_BREAK_LINES) != DONT_BREAK_LINES; 937 this.encode = (options & ENCODE) == ENCODE; 938 this.bufferLength = encode ? 3 : 4; 939 this.buffer = new byte[ bufferLength ]; 940 this.position = 0; 941 this.lineLength = 0; 942 this.suspendEncoding = false; 943 this.b4 = new byte[4]; 944 } 945 946 957 public void write(int theByte) throws java.io.IOException { 958 if( suspendEncoding ) 960 { 961 super.out.write( theByte ); 962 return; 963 } 965 if( encode ) { 966 buffer[ position++ ] = (byte)theByte; 967 if( position >= bufferLength ) { 969 out.write( encode3to4( b4, buffer, bufferLength ) ); 970 971 lineLength += 4; 972 if( breakLines && lineLength >= MAX_LINE_LENGTH ) 973 { 974 out.write( NEW_LINE ); 975 lineLength = 0; 976 } 978 position = 0; 979 } } else { 981 if( DECODABET[ theByte & 0x7f ] > WHITE_SPACE_ENC ) 983 { 984 buffer[ position++ ] = (byte)theByte; 985 if( position >= bufferLength ) { 987 int len = Base64.decode4to3( buffer, 0, b4, 0 ); 988 out.write( b4, 0, len ); 989 position = 0; 991 } } else if( DECODABET[ theByte & 0x7f ] != WHITE_SPACE_ENC ) { 993 throw new java.io.IOException ( "Invalid character in Base64 data." ); 994 } } } 998 999 1000 1008 public void write( byte[] theBytes, int off, int len ) throws java.io.IOException { 1009 if( suspendEncoding ) { 1011 super.out.write( theBytes, off, len ); 1012 return; 1013 } 1014 1015 for( int i = 0; i < len; i++ ) { 1016 write( theBytes[ off + i ] ); 1017 } 1018 1019 } 1020 1021 1024 public void flushBase64() throws java.io.IOException { 1025 if( position > 0 ) { 1026 if( encode ) { 1027 out.write( encode3to4( b4, buffer, position ) ); 1028 position = 0; 1029 } else { 1030 throw new java.io.IOException ( "Base64 input not properly padded." ); 1031 } 1032 } 1033 } 1034 1035 1038 public void close() throws java.io.IOException { 1039 flushBase64(); 1041 1042 super.close(); 1045 1046 buffer = null; 1047 out = null; 1048 } 1049 1050 1055 public void suspendEncoding() throws java.io.IOException { 1056 flushBase64(); 1057 this.suspendEncoding = true; 1058 } 1059 1060 1065 public void resumeEncoding() { 1066 this.suspendEncoding = false; 1067 } 1068 } 1069 1070} 1071 | Popular Tags |