10年 Java程序员,硬核人生!勇往直前,永不退缩!

欢迎围观我的git:https://github.com/R1310328554/spring_security_learn 寻找志同道合的有志于研究技术的朋友,关注本人微信公众号: 觉醒的码农,或Q群 165874185

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

 

BASE64  是完全可逆的, 他的原理不难理解;

首先需要知道,图片转换成base64并不是加解密,而是编解码,主要的作用不在于安全性,而在于让内容能在各个网关间无错的传输,这才是Base64编码的核心作用。

1 base64编码原理

Base64编码是基于64个字符A-Z,a-z,0-9,+,/的编码方式,因为2的6次方正好为64,所以用6位就可以表示出这64个字符了。一个字节是8位,而6位就能表达64个字符,所以取3个字符(3*8 =24位)就可以凑齐24位,然后把24位转换成4个6位的字符,然后在字节前面都填两个高位 0,形成4个新的字符。

编码流程: 以3个字符为一组,然后针对每组,首先获取每个字符的ASCII编码(字符'a'=97=01100001),然后将ASCII编码转换成8bit的二进制,得到一组3*8=24bit 的字节。然后再将这24bit划分为4个6bit的字节,并在每个6bit的字节前面都填两个高位0,得到4个8bit的字节,然后将这4个8bit的字节转换成十进制

2 base64解码原理

(1)先去掉等号;

(2)再根据编码表,找编码字符对应的编码值;

(3)取各编码值的8位二进制值,去掉每个二进制的前2位的0值,然后连接形成二进制串;

(4)对上述二进制串,从前到后,每8位构成一个字节的数据;多余的末尾0值去掉;

 

 

很多的各类的开源框架 都有BASE64  实现, 为什么会这么多呢? 其区别是? 

 

 

 

这么多,应该选择哪一个呢?

一般还是 java.util.Base64 吧,如果是 sun.misc.BASE64Encoder , 那么会出现换行。

 

 

测试如下:

    public static void test() {
        String path = "C\\\\lk\\\\Documents\\\\mmm\\\\15.驱动\\\\hp M1005 光盘\\\\Espanol\\\\Driver\\\\prn32xl.avi\"rs\\\\lk\\\\Documents\\\\mmm\\\\15.驱动\\\\hp M1005 光盘\\\\Espanol\\\\Driver\\\\prn32xl.avi\"";

        BASE64Encoder encoder = new BASE64Encoder();
        // 每76 个字符一行(why, 源码里面sun.misc.BASE64Encoder.bytesPerLine 返回是57,而转为base64之后,原来每三个字节会变成4个字节,从而 57 / 3 * 4 = 76)
        System.out.println("base64换行测试:\n" + encoder.encode(path.getBytes()));
        System.out.println(Base64Utils.encodeToString(path.getBytes())); // 这个就不会换行
System.out.println(Base64.getEncoder().encodeToString(path.getBytes())); // java.util.Base64, 也 不会换行
System.out.println();
/*
        下面打印
            base64结果为:QkNlRA==
            base64结果为:QUJD
            base64结果为:QUJDRA==
            base64结果为:QUJDRQ==
            base64结果为:QUJDRWY=
         */
        System.out.println("BASE64 加密规律测试 ");
        System.out.println("base64结果为:" + encoder.encode("BCeD".getBytes()));
        System.out.println("base64结果为:" + encoder.encode("ABC".getBytes()));//三个字节会变成4个字节: QUJD; 没有=
        System.out.println("base64结果为:" + encoder.encode("ABCD".getBytes()));// 同上,前三个字节是相同的,从而base64结果的前4个字节,也是相同的;  为:QUJDRA==
        System.out.println("base64结果为:" + encoder.encode("ABCE".getBytes()));// 两个=
        System.out.println("base64结果为:" + encoder.encode("ABCEf".getBytes()));// 一个=
        System.out.println();

        System.out.println("BASE64 URLEncode 乱码问题测试 ");
        String d = URLEncoder.encode("https://www.jiguang.cn/portal/#/dev/app/1d7dc64658cb11920a965336/info+1");
        System.out.println("d = " + d); // :、/、空格、+ 号 全部变为 %xx

        List<NameValuePair> d1 = URLEncodedUtils.parse(path, StandardCharsets.UTF_8);
        System.out.println("d1 = " + d1); // 有乱码: d1 = [C\\lk\\Documents\\mmm\\15.q�\\hp M1005 I�\\Espanol\\Driver\\prn32xl.avi"rs\\lk\\Documents\\mmm\\15.q�\\hp M1005 I�\\Espanol\\Driver\\prn32xl.avi"]
        List<NameValuePair> aaURLEncodedUtils = URLEncodedUtils.parse(path, Charset.forName("GBK"));// 有乱码:  大概因为url urlDecode后无法包含汉字
        System.out.println("d1 = " + aaURLEncodedUtils);
        System.out.println();

        /*
          下面的 有细微区别:
            encodeToUrlSafeString = YWJjZWRmZ2hpamtsbW5vcHFyZXN0dXZ3eHl6L0FCQyvmkanmlq_lr4bnoIHliqDlr4bop6Plr4Y=
            encodeToString = YWJjZWRmZ2hpamtsbW5vcHFyZXN0dXZ3eHl6L0FCQyvmkanmlq/lr4bnoIHliqDlr4bop6Plr4Y=
         */
        System.out.println("BASE64 encodeToUrlSafeString 测试 ");
        String str = "abcedfghijklmnopqrestuvwxyz/ABC+摩斯密码加密解密";
        String s = Base64Utils.encodeToUrlSafeString(str.getBytes());
        System.out.println("" + s);
        s = Base64Utils.encodeToString(str.getBytes());
        System.out.println("" + s);
        System.out.println();
        /*
          下面的 有细微区别:
            aHR0cDovL3d3d3cuYmFpZHUuY29tL2RmZGZkZmRmL2RmZGY9d-a1i-ivleWTpnJkZmRmd2UxMjMxajJzK2RmYWRmZGY=
            aHR0cDovL3d3d3cuYmFpZHUuY29tL2RmZGZkZmRmL2RmZGY9d+a1i+ivleWTpnJkZmRmd2UxMjMxajJzK2RmYWRmZGY=
         */
        String url = "http://wwww.baidu.com/dfdfdfdf/dfdf=w测试哦rdfdfwe1231j2s+dfadfdf";
        System.out.println(Base64Utils.encodeToUrlSafeString(url.getBytes()));
        System.out.println(Base64Utils.encodeToString(url.getBytes()));

    }

 

参考:


链接:https://juejin.cn/post/6913814643618086925

 

posted on 2021-10-15 20:18  CanntBelieve  阅读(505)  评论(0编辑  收藏  举报