content: package com.alimama.mdrill.adhoc;
  
  public class Base64Encode
  {
  
  
      private final static byte BYTE_TABLE[] =
      {
          'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
  
          'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
  
          'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
  
          'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
      };
  
      public static String encode( byte[] src, int srcOffset, int srcLength )
      {
          //if( src == null || srcOffset < 0 || srcLength < 0 || srcOffset + 1 > src.length || srcOffset + srcLength > src.length ){ return null; }
  
          if( src == null || srcOffset < 0 || srcLength < 1 || srcOffset + srcLength > src.length ){ return null; }
  
          byte[] buffer = new byte[( ( srcLength + 2 ) / 3 ) * 4];
  
          int round = srcLength / 3, remain = srcLength % 3;
  
          int srcIndex = srcOffset, destIndex = 0, b1, b2, b3;
  
          for( int j = 0; j < round; j ++ )
          {
              b1 = src[srcIndex ++] & 0xFF;
  
              b2 = src[srcIndex ++] & 0xFF;
  
              b3 = src[srcIndex ++] & 0xFF;
  
              buffer[destIndex ++] = BYTE_TABLE[b1 >> 2];
  
              buffer[destIndex ++] = BYTE_TABLE[b1 << 4 & 0x3F | b2 >> 4];
  
              buffer[destIndex ++] = BYTE_TABLE[b2 << 2 & 0x3F | b3 >> 6];
  
              buffer[destIndex ++] = BYTE_TABLE[b3 & 0x3F];
          }
  
          if( remain > 0 )
          {
              b1 = src[srcIndex ++] & 0xFF;
  
              buffer[destIndex ++] = BYTE_TABLE[b1 >> 2];
  
              if( remain == 1 )
              {
                  buffer[destIndex ++] = BYTE_TABLE[b1 << 4 & 0x3F];
  
                  buffer[destIndex ++] = '=';
  
                  buffer[destIndex ++] = '=';
              }
              else  //remain == 2
              {
                  b2 = src[srcIndex ++] & 0xFF;
  
                  buffer[destIndex ++] = BYTE_TABLE[b1 << 4 & 0x3F | b2 >> 4];
  
                  buffer[destIndex ++] = BYTE_TABLE[b2 << 2 & 0x3F];
  
                  buffer[destIndex ++] = '=';
              }
          }
  
          return new String( buffer, 0, destIndex );
      }
  
      public static int encode( byte[] src, int srcOffset, int srcLength, byte[] dest, int destOffset )
      {
          //if( src == null || srcOffset < 0 || srcLength < 0 || srcOffset + 1 > src.length || srcOffset + srcLength > src.length ){ return -1; }
  
          if( src == null || dest == null || srcOffset < 0 || destOffset < 0 || srcLength < 1 || srcOffset + srcLength > src.length ){ return -1; }
  
          int destLength = ( srcLength + 2 ) / 3 * 4;  //destLength always large then zero
  
          if( /*destLength < 1 ||*/ destOffset + destLength > dest.length ){ return -1; }
  
          int round = srcLength / 3, remain = srcLength % 3;
  
          int srcIndex = srcOffset, destIndex = destOffset, b1, b2, b3;
  
          for( int j = 0; j < round; j ++ )
          {
              b1 = src[srcIndex ++] & 0xFF;
  
              b2 = src[srcIndex ++] & 0xFF;
  
              b3 = src[srcIndex ++] & 0xFF;
  
              dest[destIndex ++] = BYTE_TABLE[b1 >> 2];
  
              dest[destIndex ++] = BYTE_TABLE[b1 << 4 & 0x3F | b2 >> 4];
  
              dest[destIndex ++] = BYTE_TABLE[b2 << 2 & 0x3F | b3 >> 6];
  
              dest[destIndex ++] = BYTE_TABLE[b3 & 0x3F];
          }
  
          if( remain > 0 )
          {
              b1 = src[srcIndex ++] & 0xFF;
  
              dest[destIndex ++] = BYTE_TABLE[b1 >> 2];
  
              if( remain == 1 )
              {
                  dest[destIndex ++] = BYTE_TABLE[b1 << 4 & 0x3F];
  
                  dest[destIndex ++] = '=';
  
                  dest[destIndex ++] = '=';
              }
              else  //remain == 2
              {
                  b2 = src[srcIndex ++] & 0xFF;
  
                  dest[destIndex ++] = BYTE_TABLE[b1 << 4 & 0x3F | b2 >> 4];
  
                  dest[destIndex ++] = BYTE_TABLE[b2 << 2 & 0x3F];
  
                  dest[destIndex ++] = '=';
              }
          }
  
          return destIndex;
      }
  }
  