base64码

定义

Base64是一种基于64个可打印字符来表示二进制数据的表示方法。由于2的6次方等于64,所以每6个位元为一个单元,对应某个可打印字符。三个字节有24个位元,对应于4个Base64单元,即3个字节需要用4个可打印字符来表示。它可用来作为电子邮件的传输编码。在Base64中的可打印字符包括字母A-Z、a-z、数字0-9 ,这样共有62个字符,此外两个可打印符号在不同的系统中而不同。一些如uuencode的其他编码方法,和之后binhex的版本使用不同的64字符集来代表6个二进制数字,但是它们不叫Base64。
Base64常用于在通常处理文本数据的场合,表示、传输、存储一些二进制>数据。包括MIME的email,email via MIME, 在XML中存储复杂数据.

Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读。

base64 编码表 索引表
在这里插入图片描述
维基百科中 的例子 查表 转换
在这里插入图片描述

维基百科中是这样 解释的

将String 转 成Base64 码

思路

  1. 建立 base64 码表 用char[]数组存取 用数组的优势: 下标就对应BASE64 的 索引 很方便
  2. 将字符串 转换成 byte 数组 (坑: 转换成char数组的话 就只能 转编译 字母和数值 因为 都是一个字节的 其他的都不行 特别是中文 在utf-8 是 3个字节 在gbk 是两个字节 这还只是 常用字 生僻字,表情 的字节更多了)
  3. 按照 base64 的规则 将8位对应为6位 原来的编码3个字节 3乘8位 base64码 4乘6位 我们可以将24 位作为一组 而int 有4个字节 32位 我们可以用int 去装
  4. 上面说了 可以将24位作为一组 对于原码 不一定会被8整除 在末尾我们可以 增加 8位 或 16 位 也就是1字节或2字节;
  5. 将int值查表 获得对应的字符 char[]
// 思路一
private static final char[] BASE64 = {
            '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', '+', '/'
    };
//思路二
byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
//思路四
if (bytes.length % 3 == 1) {
// 数组 扩容 增加两个字节 也就是16位
     byte[] arr2 = Arrays.copyOf(bytes, bytes.length + 2);
if (bytes.length % 3 == 2) {
// 数组 扩容 增加一个字节 也就是8位
     byte[] arr2 = Arrays.copyOf(bytes, bytes.length + 1);
//byte 数组扩容
private static char[] stringToBase64(String str) {
        byte[] bytes = str.getBytes(StandardCharsets.UTF_8);


        if (bytes.length % 3 == 1) {
            // 数组
            byte[] arr2 = Arrays.copyOf(bytes, bytes.length + 2);

            char[] ppp = ppp(arr2);

            ppp[ppp.length - 2] = '=';
            ppp[ppp.length - 1] = '=';
            return ppp;
        }

        if (bytes.length % 3 == 2) {
            byte[] arr2 = Arrays.copyOf(bytes, bytes.length + 1);
            char[] ppp = ppp(arr2);
            ppp[ppp.length - 1] = '=';
            return ppp;
        }

        char[] ppp = ppp(bytes);
        return ppp;
    }
//核心代码  将byte 先转成 int 也就是索引  在查表
public static char[] ppp(byte[] bytes) {
        int k = 0;
        int p = 0;
        char[] oo = new char[bytes.length / 3 * 4];
        while (k < oo.length) {
//            int i = ((bytes[0] << 16) | (bytes[1] << 8) | (bytes[2]));
            int i = (((bytes[p] & 0xFF) << 16) |
                    ((bytes[p + 1] & 0xFF) << 8) |
                    (bytes[p + 2] & 0xFF));

            int d3 = i & 0x3F;
            int d2 = i >>> 6 & 0x3F;
            int d1 = i >>> 12 & 0x3F;
            int d0 = i >>> 18 & 0x3F;

            oo[k] = BASE64[d0];
            oo[k + 1] = BASE64[d1];
            oo[k + 2] = BASE64[d2];
            oo[k + 3] = BASE64[d3];
            p = p + 3;
            k = k + 4;
        }

        return oo;
    }

将utf-8码 转成 base64 码 完整源代码

public class base2 {
    private static final char[] BASE64 = {
            '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 a = "测试卡次数45";
        char[] chars = stringToBase64(a);
        String s = String.valueOf(chars);

        System.out.println(s);

        //下面是将base64码转成 utf-8 码的 

//        byte[] bytes = baseToString(s);

 //       String s1 = new String(bytes, StandardCharsets.UTF_8);
 //       System.out.println(s1);

//
//        char[] chars1 = baseToString(s);
//        String s1 = String.valueOf(chars1);
//
//        System.out.println(s1);


    }

    /**
     * 将转成 base64编码  返回 字符数组
     *
     * @param str 正常字符串
     * @return
     */

    private static char[] stringToBase64(String str) {
        byte[] bytes = str.getBytes(StandardCharsets.UTF_8);


        if (bytes.length % 3 == 1) {
            // 数组
            byte[] arr2 = Arrays.copyOf(bytes, bytes.length + 2);

            char[] ppp = ppp(arr2);

            ppp[ppp.length - 2] = '=';
            ppp[ppp.length - 1] = '=';
            return ppp;
        }

        if (bytes.length % 3 == 2) {
            byte[] arr2 = Arrays.copyOf(bytes, bytes.length + 1);
            char[] ppp = ppp(arr2);
            ppp[ppp.length - 1] = '=';
            return ppp;
        }

        char[] ppp = ppp(bytes);
        return ppp;
    }

    public static char[] ppp(byte[] bytes) {
        int k = 0;
        int p = 0;
        char[] oo = new char[bytes.length / 3 * 4];
        while (k < oo.length) {
//            int i = ((bytes[0] << 16) | (bytes[1] << 8) | (bytes[2]));
            int i = (((bytes[p] & 0xFF) << 16) |
                    ((bytes[p + 1] & 0xFF) << 8) |
                    (bytes[p + 2] & 0xFF));

            int d3 = i & 0x3F;
            int d2 = i >>> 6 & 0x3F;
            int d1 = i >>> 12 & 0x3F;
            int d0 = i >>> 18 & 0x3F;

            oo[k] = BASE64[d0];
            oo[k + 1] = BASE64[d1];
            oo[k + 2] = BASE64[d2];
            oo[k + 3] = BASE64[d3];
            p = p + 3;
            k = k + 4;
        }

        return oo;
    }
}


将base64 码 转回 utf-8 码

逆向思路

源代码

 public static byte[] baseToString(String base64) {
        char[] chars = base64.toCharArray();


        byte[] bytes = new byte[(base64.length() / 4 * 3)];

        int bytesI = 0;
        int d0 = 0;
        int d1 = 0;
        int d2 = 0;
        int d3 = 0;
        for (int i = 0; i < chars.length; i += 4) {
            for (int j = 0; j < 64; j++) {
                if (chars[i] == BASE64[j]) d0 = j;
                if (chars[i + 1] == BASE64[j]) d1 = j;
                if (chars[i + 2] == BASE64[j]) d2 = j;
                if (chars[i + 3] == BASE64[j]) d3 = j;
            }


            int v = d3 | d2 << 6 | d1 << 12 | d0 << 18;

            bytes[bytesI] = (byte) (v >> 16 & 0xFF);

//            if (!(ys == 2 && (i == chars.length - 1)))
                bytes[bytesI + 1] = (byte) (v >> 8 & 0xFF);
//            if (!(ys >= 1 && (i == chars.length - 1)))
                bytes[bytesI + 2] = (byte) (v & 0xFF);

            bytesI += 3;
        }


        if (chars[chars.length - 1] == '=') {
            if (chars[chars.length - 2] == '=') {
                byte[] bytes1 = new byte[bytes.length - 2];
                for (int i = 0; i < bytes1.length; i++) {
                    bytes1[i] = bytes[i];
                }
                return bytes1;
            }
            byte[] bytes1 = new byte[bytes.length - 1];
            for (int i = 0; i < bytes1.length; i++) {
                bytes1[i] = bytes[i];
            }
            return bytes1;

        }
        return bytes;
    }

维基百科链接 BASE64

总结: base64 码现在的网络传输 用它的情况 非常多 像图片 音频 流媒体; 对于我来说 让我了解了编码的一些规则 是怎么编码的
有什么问题可以私聊我

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值