public static String encode(byte[] in) {
        int fourB64Bytes = 0;
        StringBuffer sb = new StringBuffer();
        int posIn = 0;
        for (posIn = 0; posIn < in.length; posIn++) {
            int oneByte = in[posIn];    // in 0..255, not -128..127 
            if (oneByte < 0) {
                oneByte += 256;
            }
            fourB64Bytes = (fourB64Bytes << 8) + oneByte;
            if (posIn % 3 == 2) {
                sb.append((char)ENCODE_TABLE[(fourB64Bytes >> 18) & 0x3F]);
                sb.append((char)ENCODE_TABLE[(fourB64Bytes >> 12) & 0x3F]);
                sb.append((char)ENCODE_TABLE[(fourB64Bytes >> 6) & 0x3F]);
                sb.append((char)ENCODE_TABLE[fourB64Bytes & 0x3F]);
                fourB64Bytes = 0;
            }
        }
        posIn--;
        switch (posIn % 3) {
        case 0:
            fourB64Bytes = fourB64Bytes << 4;   //pad with 0000
            sb.append((char)ENCODE_TABLE[(fourB64Bytes >> 6) & 0x3F]);
            sb.append((char)ENCODE_TABLE[fourB64Bytes & 0x3F]);
            sb.append((char)PAD);
            sb.append((char)PAD);
            fourB64Bytes = 0;
            break;

        case 1:
            fourB64Bytes = fourB64Bytes << 2;   //pad with 00
            sb.append((char)ENCODE_TABLE[(fourB64Bytes >> 12) & 0x3F]);
            sb.append((char)ENCODE_TABLE[(fourB64Bytes >> 6) & 0x3F]);
            sb.append((char)ENCODE_TABLE[fourB64Bytes & 0x3F]);
            sb.append((char)PAD);
            fourB64Bytes = 0;
            break;

        }
        return sb.toString();
    }