import java.util.Base64;

/**
 * Description
 * Created by vinc on 2017/9/6.
 * base64 编解码
 *
 * 编码
 * 将每个字节补为8位的2进制,3个字节为1组
 * 每组6位,转化为10进制到基本字符表toBase64URL中找对应字符
 * 不是3的倍数补成3的倍数填充1或2个0字节,转成10进制找对应字符
 *
 * 解码就是掉个个
 */
public class Base64Application {
    private static final char[] toBase64URL = {
            '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 void main(String[] args) {
        String org = "degxgdew";
        System.out.println("org:" + org);
        System.out.println();
        byte[] encode1 = Base64.getEncoder().encode(org.getBytes());
        System.out.println(new String(encode1));
        byte[] decode1 = Base64.getDecoder().decode(new String(encode1));
        System.out.println(new String(decode1));
        System.out.println();
        String encode = mbase64Code(org);
        System.out.println(encode);
        String decode = mbase64Decode(encode);
        System.out.println(decode);
    }

    //base64解码
    private static String mbase64Decode(String encode) {
        encode = encode.replaceAll("=", "");
        char[] chars = encode.toCharArray();
        StringBuilder deStr = new StringBuilder();
        f1:
        for (int i = 0; i < chars.length; i++) {
            for (int j = 0; j < toBase64URL.length; j++) {
                if (toBase64URL[j] == chars[i]) {
                    String indexStr = Integer.toBinaryString(j);
                    int length = indexStr.length();
                    for (int k = 0; k < 6 - length; k++) {
                        indexStr = "0" + indexStr;
                    }
                    deStr.append(indexStr);
                    continue f1;
                }
            }
        }
        StringBuilder result = new StringBuilder();
        int index = 0;
        for (int i = 1; i <= deStr.length() / 8; i++) {
            result.append((char) Integer.valueOf(deStr.substring(index, i * 8), 2).intValue());
            index += 8;
        }
        return result.toString();
    }

    //base64编码
    private static String mbase64Code(String abc) {
        byte[] bytes = abc.getBytes();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String bitStr = Integer.toBinaryString(bytes[i]);
            int len = bitStr.length();
            for (int j = 0; j < 8 - len; j++) {
                bitStr = "0" + bitStr;
            }
            sb.append(bitStr);
        }
        while (sb.length() % 3 != 0) {
            sb.append("0");
        }
        StringBuilder result = new StringBuilder();
        for (int j = 0; j < sb.length() / 6; j++) {
            result.append(toBase64URL[Integer.parseInt(sb.substring(j * 6, (j + 1) * 6), 2)]);
        }
        int leng = abc.length() % 3;
        for (int i = 0; i < 3 - leng % 3; i++) {
            result.append("=");
        }
        return result.toString();
    }
}