// base64 encoder // // Reference: ftp://ftp.isi.edu/in-notes/rfc2045.txt // // R. Perry, April 2000 // // added encode_skip_leading_zero() for BigInteger byte arrays // for consistency with other base encodings - November 2013 // // changed StringBuffer to StringBuilder (no sync ok) - December 2015 // package Base64; /** * Encode bytes into a base64 string. *

* This class is designed using internal buffers so that * the caller can encode bytes and byte arrays, then obtain the final * encoded result using the flush() method. *

* Example usage (from main(), for testing): *

 *   byte[] b = new byte[4096];
 *   int n;
 *   Base64.Encoder b64 = new Base64.Encoder();
 *
 *   while( (n = System.in.read( b)) > 0)
 *     b64.encode( b, 0, n);
 *
 *   System.out.print( b64.flush());
 * 
* * @author Rick Perry * @version 5 April 2000 */ public class B64Encoder { /** * The mapping from 6-bit values to encoded characters. */ private static char[] table = { // 0 1 2 3 4 5 6 7 'A','B','C','D','E','F','G','H', // 0 'I','J','K','L','M','N','O','P', // 1 'Q','R','S','T','U','V','W','X', // 2 'Y','Z','a','b','c','d','e','f', // 3 'g','h','i','j','k','l','m','n', // 4 'o','p','q','r','s','t','u','v', // 5 'w','x','y','z','0','1','2','3', // 6 '4','5','6','7','8','9','+','/' // 7 }; /** * \n or maybe \r\n */ private static String newline = System.getProperty( "line.separator"); /** * Internal 3-byte buffer. */ private byte[] buf; /** * Internal buffer current length. */ private int buflen; /** * Encoded output. */ private StringBuilder out; /** * Encoded output current length. */ private int outlen; /** * Construct a new Encoder. */ public B64Encoder() { out = new StringBuilder(); buf = new byte[3]; outlen = buflen = 0; } /** * Encode one byte. * * @param b the byte to be encoded. */ public void encode( byte b) { buf[buflen++] = b; if( buflen == 3) { if( outlen == 76) { out.append( newline); outlen = 0; } out.append( table[ (buf[0] >>> 2) & 0x3f]); out.append( table[ ((buf[0] << 4) & 0x30) | ((buf[1] >>> 4) & 0x0f)]); out.append( table[ ((buf[1] << 2) & 0x3c) | ((buf[2] >>> 6) & 0x03)]); out.append( table[ buf[2] & 0x3f]); outlen += 4; buflen = 0; } } /** * Encode a byte array. *

* * @param b the byte array to be encoded. */ public void encode( byte[] b) { for( int i = 0; i < b.length; ++i) encode( b[i]); } /** * Encode a byte array, skipping the first byte if it is zero *

* * @param b the byte array to be encoded. */ public void encode_skip_leading_zero( byte[] b) { if( b[0] != 0) encode( b[0]); for( int i = 1; i < b.length; ++i) encode( b[i]); } /** * Encode a byte array, starting at the specified offset. *

* * @param b the byte array to be encoded. * @param offset the offset to start from in the array of bytes. * @param len the number of bytes to use, starting at offset. */ public void encode( byte[] b, int offset, int len) { for( int i = 0; i < len; ++i) encode( b[i+offset]); } /** * Return encoded output. *

* The encoder internal buffer is reset after this call is made. * * @return the encoded output string. */ public String flush() { if( buflen > 0 && outlen == 76) out.append( newline); if( buflen == 1) { out.append( table[ (buf[0] >>> 2) & 0x3F]); out.append( table[ ((buf[0] << 4) & 0x30)]); out.append( '='); out.append( '='); } else if( buflen == 2) { out.append( table[ (buf[0] >>> 2) & 0x3F]); out.append( table[ ((buf[0] << 4) & 0x30) | ((buf[1] >>> 4) & 0x0F)]); out.append( table[ ((buf[1] << 2) & 0x3C)]); out.append( '='); } out.append( newline); String s = new String( out); out.setLength( 0); outlen = buflen = 0; return s; } /** * Return encoded output. *

* The encoder internal buffer is reset after this call is made. * * @param b the final byte to be encoded. * @return the encoded output string. */ public String flush( byte b) { encode( b); return flush(); } /** * Return encoded output. *

* The encoder internal buffer is reset after this call is made. * * @param b the final byte array to be encoded. * @return the encoded output string. */ public String flush( byte[] b) { encode( b); return flush(); } /** * Return encoded output. *

* The encoder internal buffer is reset after this call is made. * * @param b the final byte array to be encoded. * @param offset the offset to start from in the array of bytes. * @param len the number of bytes to use, starting at offset. * @return the encoded output string. */ public String flush( byte[] b, int offset, int len) { encode( b, offset, len); return flush(); } /** * Just for testing. */ public static void main( String args[]) throws Exception { byte[] b = new byte[4096]; int n; // Base64.Encoder b64 = new Base64.Encoder(); B64Encoder b64 = new B64Encoder(); while( (n = System.in.read( b)) > 0) b64.encode( b, 0, n); System.out.print( b64.flush()); } }