import java.io.*;
import java.lang.*;
import java.awt.*;

public class Base64Encode
{
  static final int BYTES_PER_LINE = 57;

  int binarySize;

  byte[] binary;

  char[] text;

  int textIdx = 0;

  int textSize;

  char[] base64Char;

  public Base64Encode(byte[] binary) {
    this.binary = binary;
    binarySize = binary.length;

    base64Char = (
      "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
      "abcdefghijklmnopqrstuvwxyz" +
      "0123456789+/"
      ).toCharArray();

    textSize = (binarySize / 3) * 4 + newlineCount() + equalCount();
    text = new char[textSize];

    int block;
    int i;
    for (i = 0; i < binarySize; i += 3) {
      block = make8BitBlock(getByte(i), getByte(i + 1), getByte(i + 2));
      if (i == binarySize - 1) {
        printChar1(block);
        printChar2(block);
        printPad();
        printPad();
      }
      else
      if (i == binarySize - 2) {
        printChar1(block);
        printChar2(block);
        printChar3(block);
        printPad();
      }
      else {
        printChar1(block);
        printChar2(block);
        printChar3(block);
        printChar4(block);
        printBreak(i);
      }
    }
  }

  int newlineCount() {
    int count;
    count = binarySize / BYTES_PER_LINE;
    if (binarySize % BYTES_PER_LINE == 0)
      count--;
    return count;
  }

  int equalCount() {
    int count;
    count = binarySize % BYTES_PER_LINE;
    if (count == 0)
      return count;
    else
      return 4;
  }

  int getByte(int n) {
    int b;
    if (n < binarySize) {
      b = (int)binary[n];
      if (b >= 0)
        return b;
      return b + 256;
    }
    return 0;
  }

  int make8BitBlock(int a, int b, int c) {
    return (a << 16) + (b << 8) + c;
  }

  void print(char c) {
    text[textIdx] = base64Char[c];
    textIdx++;
  }

  void printPad() {
    text[textIdx] = '=';
    textIdx++;
  }

  void newline() {
    text[textIdx] = '\n';
    textIdx++;
  }

  void printBreak(int n) {
    if (n != binarySize - 3)
      if ((n + 3) % BYTES_PER_LINE == 0)
        newline();
  }

  void printChar1(int block) {
    print((char)((block >> 18) & 0x3f));
  }

  void printChar2(int block) {
    print((char)(((block & 0x0003f000) >> 12) & 0x3f));
  }

  void printChar3(int block) {
    print((char)(((block & 0x00000fc0) >> 6) & 0x3f));
  }

  void printChar4(int block) {
    print((char)(block &   0x0000003f));
  }

  String getText() {
    return new String(text);
  }
}
