| 1 package org.apache.ojb.broker.util; 2 3 17 18 import org.apache.ojb.broker.util.logging.LoggerFactory; 19 20 public class Base64 21 { 22 23 24 public final static boolean ENCODE = true; 25 26 27 28 public final static boolean DECODE = false; 29 30 31 32 private final static int MAX_LINE_LENGTH = 76; 33 34 35 36 private final static byte EQUALS_SIGN = (byte)'='; 37 38 39 40 private final static byte NEW_LINE = (byte)'\n'; 41 42 43 44 private final static byte[] ALPHABET = 45 { 46 (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', 47 (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', 48 (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', 49 (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', 50 (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', 51 (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', 52 (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', 53 (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z', 54 (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', 55 (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'+', (byte)'/' 56 }; 57 58 62 private final static byte[] DECODABET = 63 { 64 -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 95 }; 96 97 private final static byte BAD_ENCODING = -9; private final static byte WHITE_SPACE_ENC = -5; private final static byte EQUALS_SIGN_ENC = -1; 101 102 103 private Base64(){} 104 105 106 107 111 public static void main( String [] args ) 112 { 113 try 114 { 115 { 117 byte[] bytes1 = { (byte)2,(byte)2,(byte)3,(byte)0,(byte)9 }; byte[] bytes2 = { (byte)99,(byte)2,(byte)2,(byte)3,(byte)0,(byte)9 }; 119 System.out.println( "Bytes 2,2,3,0,9 as Base64: " + encodeBytes( bytes1 ) ); 120 System.out.println( "Bytes 2,2,3,0,9 w/ offset: " + encodeBytes( bytes2, 1, bytes2.length-1 ) ); 121 byte[] dbytes = decode( encodeBytes( bytes1 ) ); 122 System.out.print( encodeBytes( bytes1 ) + " decoded: " ); 123 for( int i = 0; i < dbytes.length; i++ ) 124 System.out.print( dbytes[i] + (i<dbytes.length-1?",":"\n") ); 125 } 127 128 129 130 { 132 java.io.FileInputStream fis = new java.io.FileInputStream ( "test.gif.b64" ); 134 Base64.InputStream b64is = new Base64.InputStream( fis, DECODE ); 135 136 byte[] bytes = new byte[0]; 137 int b = -1; 138 while( (b = b64is.read()) >= 0 ){ 139 byte[] temp = new byte[ bytes.length + 1 ]; 140 System.arraycopy( bytes,0, temp,0,bytes.length ); 141 temp[bytes.length] = (byte)b; 142 bytes = temp; 143 } b64is.close(); 145 javax.swing.ImageIcon iicon = new javax.swing.ImageIcon ( bytes ); 146 javax.swing.JLabel jlabel = new javax.swing.JLabel ( "Read from test.gif.b64", iicon,0 ); 147 javax.swing.JFrame jframe = new javax.swing.JFrame (); 148 jframe.getContentPane().add( jlabel ); 149 jframe.pack(); 150 jframe.show(); 151 152 java.io.FileOutputStream fos = new java.io.FileOutputStream ( "test.gif_out" ); 154 fos.write( bytes ); 155 fos.close(); 156 157 fis = new java.io.FileInputStream ( "test.gif_out" ); 159 b64is = new Base64.InputStream( fis, ENCODE ); 160 byte[] ebytes = new byte[0]; 161 b = -1; 162 while( (b = b64is.read()) >= 0 ){ 163 byte[] temp = new byte[ ebytes.length + 1 ]; 164 System.arraycopy( ebytes,0, temp,0,ebytes.length ); 165 temp[ebytes.length] = (byte)b; 166 ebytes = temp; 167 } b64is.close(); 169 String s = new String ( ebytes ); 170 javax.swing.JTextArea jta = new javax.swing.JTextArea ( s ); 171 javax.swing.JScrollPane jsp = new javax.swing.JScrollPane ( jta ); 172 jframe = new javax.swing.JFrame (); 173 jframe.setTitle( "Read from test.gif_out" ); 174 jframe.getContentPane().add( jsp ); 175 jframe.pack(); 176 jframe.show(); 177 178 fos = new java.io.FileOutputStream ( "test.gif.b64_out" ); 180 fos.write( ebytes ); 181 182 fis = new java.io.FileInputStream ( "test.gif.b64_out" ); 184 b64is = new Base64.InputStream( fis, DECODE ); 185 byte[] edbytes = new byte[0]; 186 b = -1; 187 while( (b = b64is.read()) >= 0 ){ 188 byte[] temp = new byte[ edbytes.length + 1 ]; 189 System.arraycopy( edbytes,0, temp,0,edbytes.length ); 190 temp[edbytes.length] = (byte)b; 191 edbytes = temp; 192 } b64is.close(); 194 iicon = new javax.swing.ImageIcon ( edbytes ); 195 jlabel = new javax.swing.JLabel ( "Read from test.gif.b64_out", iicon,0 ); 196 jframe = new javax.swing.JFrame (); 197 jframe.getContentPane().add( jlabel ); 198 jframe.pack(); 199 jframe.show(); 200 } 202 203 { 205 java.io.FileInputStream fis = new java.io.FileInputStream ( "test.gif_out" ); 207 byte[] rbytes = new byte[0]; 208 int b = -1; 209 while( (b = fis.read()) >= 0 ){ 210 byte[] temp = new byte[ rbytes.length + 1 ]; 211 System.arraycopy( rbytes,0, temp,0,rbytes.length ); 212 temp[rbytes.length] = (byte)b; 213 rbytes = temp; 214 } fis.close(); 216 217 java.io.FileOutputStream fos = new java.io.FileOutputStream ("test.gif.b64_out2"); 219 Base64.OutputStream b64os = new Base64.OutputStream( fos, ENCODE ); 220 b64os.write( rbytes ); 221 b64os.close(); 222 223 224 fis = new java.io.FileInputStream ( "test.gif.b64_out2" ); 226 byte[] rebytes = new byte[0]; 227 b = -1; 228 while( (b = fis.read()) >= 0 ){ 229 byte[] temp = new byte[ rebytes.length + 1 ]; 230 System.arraycopy( rebytes,0, temp,0,rebytes.length ); 231 temp[rebytes.length] = (byte)b; 232 rebytes = temp; 233 } fis.close(); 235 String s = new String ( rebytes ); 236 javax.swing.JTextArea jta = new javax.swing.JTextArea ( s ); 237 javax.swing.JScrollPane jsp = new javax.swing.JScrollPane ( jta ); 238 javax.swing.JFrame jframe = new javax.swing.JFrame (); 239 jframe.setTitle( "Read from test.gif.b64_out2" ); 240 jframe.getContentPane().add( jsp ); 241 jframe.pack(); 242 jframe.show(); 243 244 fos = new java.io.FileOutputStream ("test.gif_out2"); 246 b64os = new Base64.OutputStream( fos, DECODE ); 247 b64os.write( rebytes ); 248 b64os.close(); 249 javax.swing.ImageIcon iicon = new javax.swing.ImageIcon ( "test.gif_out2" ); 250 javax.swing.JLabel jlabel = new javax.swing.JLabel ( "Read from test.gif_out2", iicon,0 ); 251 jframe = new javax.swing.JFrame (); 252 jframe.getContentPane().add( jlabel ); 253 jframe.pack(); 254 jframe.show(); 255 256 } 258 259 { 261 java.io.FileInputStream fis = new java.io.FileInputStream ("D:\\temp\\testencoding.txt"); 262 Base64.InputStream b64is = new Base64.InputStream( fis, DECODE ); 263 java.io.FileOutputStream fos = new java.io.FileOutputStream ("D:\\temp\\file.zip"); 264 int b; 265 while( (b=b64is.read()) >= 0 ) 266 fos.write( b ); 267 fos.close(); 268 b64is.close(); 269 270 } 272 } catch( Exception e) 274 { e.printStackTrace(); 275 } 276 } 278 279 280 281 282 290 private static byte[] encode3to4( byte[] threeBytes ) 291 { return encode3to4( threeBytes, 3 ); 292 } 294 295 296 309 private static byte[] encode3to4( byte[] threeBytes, int numSigBytes ) 310 { byte[] dest = new byte[4]; 311 encode3to4( threeBytes, 0, numSigBytes, dest, 0 ); 312 return dest; 313 } 314 315 316 317 338 private static byte[] encode3to4( 339 byte[] source, int srcOffset, int numSigBytes, 340 byte[] destination, int destOffset ) 341 { 342 349 int inBuff = ( numSigBytes > 0 ? ((source[ srcOffset ] << 24) >>> 8) : 0 ) 354 | ( numSigBytes > 1 ? ((source[ srcOffset + 1 ] << 24) >>> 16) : 0 ) 355 | ( numSigBytes > 2 ? ((source[ srcOffset + 2 ] << 24) >>> 24) : 0 ); 356 357 switch( numSigBytes ) 358 { 359 case 3: 360 destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; 361 destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; 362 destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>> 6) & 0x3f ]; 363 destination[ destOffset + 3 ] = ALPHABET[ (inBuff ) & 0x3f ]; 364 return destination; 365 366 case 2: 367 destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; 368 destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; 369 destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>> 6) & 0x3f ]; 370 destination[ destOffset + 3 ] = EQUALS_SIGN; 371 return destination; 372 373 case 1: 374 destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; 375 destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; 376 destination[ destOffset + 2 ] = EQUALS_SIGN; 377 destination[ destOffset + 3 ] = EQUALS_SIGN; 378 return destination; 379 380 default: 381 return destination; 382 } } 385 395 public static String encodeObject( java.io.Serializable serializableObject ) 396 { 397 return encodeObject( serializableObject, true ); 398 } 400 411 public static String encodeObject(java.io.Serializable serializableObject, boolean breakLines) 412 { 413 java.io.ByteArrayOutputStream baos = null; 414 java.io.OutputStream b64os = null; 415 java.io.ObjectOutputStream oos = null; 416 417 try 418 { 419 baos = new java.io.ByteArrayOutputStream (); 420 b64os = new Base64.OutputStream(baos, Base64.ENCODE, breakLines); 421 oos = new java.io.ObjectOutputStream (b64os); 422 423 oos.writeObject(serializableObject); 424 } catch (java.io.IOException e) 426 { 427 e.printStackTrace(); 428 return null; 429 } finally 431 { 432 try 433 { 434 oos.close(); 435 } 436 catch (Exception e) 437 { 438 } 440 try 441 { 442 b64os.close(); 443 } 444 catch (Exception e) 445 { 446 } 448 try 449 { 450 baos.close(); 451 } 452 catch (Exception e) 453 { 454 } 456 } 458 return new String (baos.toByteArray()); 459 } 461 462 470 public static String encodeBytes( byte[] source ) 471 { 472 return encodeBytes( source, true ); 473 } 475 484 public static String encodeBytes( byte[] source, boolean breakLines ) 485 { 486 return encodeBytes( source, 0, source.length, breakLines ); 487 } 489 490 498 public static String encodeBytes( byte[] source, int off, int len ) 499 { 500 return encodeBytes( source, off, len, true ); 501 } 503 504 513 public static String encodeBytes( byte[] source, int off, int len, boolean breakLines ) 514 { 515 int len43 = len * 4 / 3; 516 byte[] outBuff = new byte[ ( len43 ) + ( (len % 3) > 0 ? 4 : 0 ) + (breakLines ? ( len43 / MAX_LINE_LENGTH ) : 0) ]; int d = 0; 520 int e = 0; 521 int len2 = len - 2; 522 int lineLength = 0; 523 for( ; d < len2; d+=3, e+=4 ) 524 { 525 encode3to4( source, d+off, 3, outBuff, e ); 526 527 lineLength += 4; 528 if( breakLines && lineLength == MAX_LINE_LENGTH ) 529 { 530 outBuff[e+4] = NEW_LINE; 531 e++; 532 lineLength = 0; 533 } } 536 if( d < len ) 537 { 538 encode3to4( source, d+off, len - d, outBuff, e ); 539 e += 4; 540 } 542 return new String ( outBuff, 0, e ); 543 } 545 546 554 public static String encodeString( String s ) 555 { 556 return encodeString( s, true ); 557 } 559 568 public static String encodeString( String s, boolean breakLines ) 569 { 570 return encodeBytes( s.getBytes(), breakLines ); 571 } 573 574 575 576 577 578 579 588 private static byte[] decode4to3( byte[] fourBytes ) 589 { 590 byte[] outBuff1 = new byte[3]; 591 int count = decode4to3( fourBytes, 0, outBuff1, 0 ); 592 byte[] outBuff2 = new byte[ count ]; 593 594 System.arraycopy( outBuff1, 0, outBuff2, 0, count ); 595 return outBuff2; 596 } 597 598 599 600 601 623 private static int decode4to3( byte[] source, int srcOffset, byte[] destination, int destOffset ) 624 { 625 if( source[ srcOffset + 2] == EQUALS_SIGN ) 627 { 628 int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) 632 | ( ( DECODABET[ source[ srcOffset + 1] ] & 0xFF ) << 12 ); 633 634 destination[ destOffset ] = (byte)( outBuff >>> 16 ); 635 return 1; 636 } 637 638 else if( source[ srcOffset + 3 ] == EQUALS_SIGN ) 640 { 641 int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) 646 | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 ) 647 | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) << 6 ); 648 649 destination[ destOffset ] = (byte)( outBuff >>> 16 ); 650 destination[ destOffset + 1 ] = (byte)( outBuff >>> 8 ); 651 return 2; 652 } 653 654 else 656 { 657 try{ 658 int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) 664 | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 ) 665 | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) << 6) 666 | ( ( DECODABET[ source[ srcOffset + 3 ] ] & 0xFF ) ); 667 668 669 destination[ destOffset ] = (byte)( outBuff >> 16 ); 670 destination[ destOffset + 1 ] = (byte)( outBuff >> 8 ); 671 destination[ destOffset + 2 ] = (byte)( outBuff ); 672 673 return 3; 674 }catch( Exception e){ 675 LoggerFactory.getDefaultLogger().error(""+source[srcOffset]+ ": " + ( DECODABET[ source[ srcOffset ] ] ) ); 676 LoggerFactory.getDefaultLogger().error(""+source[srcOffset+1]+ ": " + ( DECODABET[ source[ srcOffset + 1 ] ] ) ); 677 LoggerFactory.getDefaultLogger().error(""+source[srcOffset+2]+ ": " + ( DECODABET[ source[ srcOffset + 2 ] ] ) ); 678 LoggerFactory.getDefaultLogger().error(""+source[srcOffset+3]+ ": " + ( DECODABET[ source[ srcOffset + 3 ] ] ) ); 679 return -1; 680 } } 682 } 684 685 686 693 public static byte[] decode( String s ) 694 { 695 byte[] bytes = s.getBytes(); 696 return decode( bytes, 0, bytes.length ); 697 } 699 700 |