java自定义base64

public class MyBase64 implements Codec {

    private final static Logger LOGGER = LoggerFactory.getLogger(MyBase64.class);

    private final static String STANDARD_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    private static final int RANGE = 0xff;

    private final String alphabet;

    private char[] base64ByteToStr;

    private byte[] strToBase64Byte = new byte[128];

    public MyBase64(String alphabet) {
        this.alphabet = alphabet;
        init();
    }

    private void init() {
        base64ByteToStr = alphabet.toCharArray();

        for (int i = 0; i <= strToBase64Byte.length - 1; i++) {
            strToBase64Byte[i] = -1;
        }
        for (int i = 0; i <= base64ByteToStr.length - 1; i++) {
            strToBase64Byte[base64ByteToStr[i]] = (byte) i;
        }

    }

    /**
     * 加密
     *
     * @param bytesToEncode
     * @return
     */
    @Override
    public byte[] encode(byte[] bytesToEncode) {
        StringBuilder res = new StringBuilder();
        //per 3 bytes scan and switch to 4 bytes
        for (int i = 0; i <= bytesToEncode.length - 1; i += 3) {
            byte[] enBytes = new byte[4];
            byte tmp = (byte) 0x00;// save the right move bit to next position's bit
            //3 bytes to 4 bytes
            for (int k = 0; k <= 2; k++) {// 0 ~ 2 is a line
                if ((i + k) <= bytesToEncode.length - 1) {
                    enBytes[k] = (byte) (((((int) bytesToEncode[i + k] & RANGE) >>> (2 + 2 * k))) | (int) tmp);//note , we only get 0 ~ 127 ???
                    tmp = (byte) (((((int) bytesToEncode[i + k] & RANGE) << (2 + 2 * (2 - k))) & RANGE) >>> 2);
                } else {
                    enBytes[k] = tmp;
                    tmp = (byte) 64;//if tmp > 64 then the char is '=' hen '=' -> byte is -1 , so it is EOF or not print char
                }
            }
            enBytes[3] = tmp;//forth byte
            //4 bytes to encode string
            for (int k = 0; k <= 3; k++) {
                if ((int) enBytes[k] <= 63) {
                    res.append(base64ByteToStr[(int) enBytes[k]]);
                } else {
                    res.append('=');
                }
            }
        }
        try {
            return res.toString().getBytes(CharsetUtil.UTF_8);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 解密
     *
     * @param bytesEncoded
     * @return
     */
    @Override
    public byte[] decode(byte[] bytesEncoded) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();//destination bytes, valid string that we want
        byte[] base64bytes = new byte[bytesEncoded.length];
        //get the base64 bytes (the value is -1 or 0 ~ 63)
        for (int i = 0; i <= bytesEncoded.length - 1; i++) {
            int ind = (int) bytesEncoded[i];
            base64bytes[i] = strToBase64Byte[ind];
        }
        //base64 bytes (4 bytes) to normal bytes (3 bytes)
        for (int i = 0; i <= base64bytes.length - 1; i += 4) {
            byte[] deBytes = new byte[3];
            int delen = 0;// if basebytes[i] = -1, then debytes not append this value
            byte tmp;
            for (int k = 0; k <= 2; k++) {
                if ((i + k + 1) <= base64bytes.length - 1 && base64bytes[i + k + 1] >= 0) {
                    tmp = (byte) (((int) base64bytes[i + k + 1] & RANGE) >>> (2 + 2 * (2 - (k + 1))));
                    deBytes[k] = (byte) ((((int) base64bytes[i + k] & RANGE) << (2 + 2 * k) & RANGE) | (int) tmp);
                    delen++;
                }
            }
            for (int k = 0; k <= delen - 1; k++) {
                bos.write((int) deBytes[k]);
            }
        }
        return bos.toByteArray();
    }

    private void showDecoder() throws Exception {
        String str = "";
        for (int i = 1; i <= strToBase64Byte.length; i++) {
            str += (int) strToBase64Byte[i - 1] + ",";
            if (i % 10 == 0 || i == strToBase64Byte.length) {
                LOGGER.info(str);
                str = "";
            }
        }
    }

    /**
     * 随机一个 Alphabet
     *
     * @return
     */
    public static String randomAlphabet() {
        StringBuilder temp = new StringBuilder(STANDARD_ALPHABET);
        StringBuilder out = new StringBuilder();
        while (true) {
            int size = temp.length();
            if (size <= 0) {
                break;
            }
            int index = RandomUtil.randomInt(size);
            out.append(temp.charAt(index));
            temp.deleteCharAt(index);
        }
        return out.toString();
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值