base64加密算法详解,以及使用时可能出现的问题

1、base64加密算法

1、加密算法简述

base64:因为HTTP协议是文本协议,传输信息时只支持可打印字符,所以为了使HTTP协议能够支持传输图片、文件等等数据,只能先将数据转换成base64的字符串来保存。
可打印字符:ASCII码中一共有128个字符(0-127),其中只有32-126这95个字符属于可打印字符,base64选取的64个字符是A-Z,a-z,0-9,+ 和 /。如下所示,1就是B,63就是/,另外还有一个 = 号用于标识结尾(不一定都有,后面会解释)。

        /**
         * This array is a lookup table that translates 6-bit positive integer
         * index values into their "Base64 Alphabet" equivalents as specified
         * in "Table 1: The Base64 Alphabet" of RFC 2045 (and RFC 4648).
         */
        private static final char[] toBase64 = {
            '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', '+', '/'
        };

原理:算法将这64个字符通过6位来一一对应起来,表示为000000-111111。然后将三个字节的数据拆分成4份分别使用这64个字符来表示。也就是说通过base64加密后,每三个字符都会最终变成四个字符。

2、使用方法

使用的是java.util.Base64提供的方法,加解密分别对应的是Base64中的两个内部类,需要jdk版本至少大于等于1.8。
加密:

//从流中获取到的字节数组
byte[] bytes = new byte[3072];
Base64.getEncoder().encodeToString(bytes);

解密:

//使用base64将流加密之后的字符串
StringBuilder encode = new StringBuilder();
Base64.getDecoder().decode(encode.toString());
3、简单实现
    public static void main(String[] args) {
        long t1 = System.currentTimeMillis();
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            bis = new BufferedInputStream(new FileInputStream("F:\\1.pdf")); 	//读取数据
            bos = new BufferedOutputStream(new FileOutputStream("F:\\6.pdf"));	//写数据
            byte[] bytes = new byte[3072];		//字节数组
            byte[] decode;
            StringBuilder encode = new StringBuilder();
            while (bis.read(bytes) != -1) { //读取到字节数组中
                System.out.println("读取...");
                encode.append(Base64.getEncoder().encodeToString(bytes));  //每次将加密后的字符串追加到encode中
            }
            decode = Base64.getDecoder().decode(encode.toString());		//将encode解密
            bos.write(decode);	//写到文件中
            System.out.println("end...");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bis != null) {
                    bis.close();
                }
                if (bos != null) {
                    bos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        long t2 = System.currentTimeMillis();
        System.out.println(t2 - t1);
    }
4、注意事项
如果加密的字节数不是3的倍数呢?

比如最后只剩下一个字节了。base64首先将后面两个字节全部使用0来代替,将这个字节前6位放入一个空间,后两位放入一个空间,然后低位补0。并且使用 = 号来标识,如果刚好是3的倍数的话就不需要补0操作,自然也就不会有 = 号。

一个字节
11111111

先补成三个字节
11111111 00000000 00000000

分割成四个6位的字符
111111 110000 000000 000000
63		48		0		0

加密后的结果
\w==
能不能分批加密

可以发现,上面的简单测试用例就是使用的分批加密,然后统一解密的方式。主要为了防止文件过大,转换成byte数组后超出了常数的大小而报错。而使用分批加密必须要注意的点就是需要以3的倍数来获取流的数据,否则加密出来的结果带有=号,在解密时会出现解密出错的情况。

byte[] bytes = new byte[3072]; //每次取用的大小必须是3的倍数
加解密的大小不一致

如果不是分批读取的话,是不会存在这种情况的,查看是否对文件的写操作是追加情况。
如果是分批操作,如果数据源是使用多个字节代替一位字符的情况,就有可能取数据的时候取得不完整而导致加解密后得大小不一致,推荐使用1024的倍数来取数据。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值