code: public static String toBase64(byte[] data) {
          if (data == null) {
              return null;
          }
  
          int len = data.length;
          if (len == 0) {
              return "";
          }
  
          int olen = 4 * ((len + 2) / 3);
          char[] chars = new char[olen];
  
          int iidx = 0;
          int oidx = 0;
          int charsLeft = len;
          while (charsLeft > 0) {
              int b0 = data[iidx++] & 0xff;
              int b1 = (charsLeft > 1) ? data[iidx++] & 0xff : 0;
              int b2 = (charsLeft > 2) ? data[iidx++] & 0xff : 0;
              int b24 = (b0 << 16) | (b1 << 8) | b2;
  
              int c0 = (b24 >> 18) & 0x3f;
              int c1 = (b24 >> 12) & 0x3f;
              int c2 = (b24 >> 6) & 0x3f;
              int c3 = b24 & 0x3f;
  
              chars[oidx++] = base64Chars[c0];
              chars[oidx++] = base64Chars[c1];
              chars[oidx++] = (charsLeft > 1) ? base64Chars[c2] : '=';
              chars[oidx++] = (charsLeft > 2) ? base64Chars[c3] : '=';
  
              charsLeft -= 3;
          }
  
          return new String(chars);
      }
docs: Converts a byte array into a base 64 encoded string. Null is encoded as
  null, and an empty array is encoded as an empty string. Otherwise, the byte
  data is read 3 bytes at a time, with bytes off the end of the array padded
  with zeros. Each 24-bit chunk is encoded as 4 characters from the sequence
  [A-Za-z0-9$_]. If one of the source positions consists entirely of padding
  zeros, an '=' character is used instead.
  
  @param data a byte array, which may be null or empty
  @return a String