为什么BASE64编码和解码总是出问题

1.可以尝试使用Base64.getEncoder().withoutPadding()不填充方式

 

2.如果涉及网络url传输,其中的+和/会被转义成_和-

 

3.【重点】如果编码问题都是对的,那么,很可能是被底层的原理给坑了

我遇到的就是使用流进行数据编解码,流比较常见的就是使用了缓存,理解了b64的原理,就能知道如果我们希望每次编解码没有其补位编码【最后一次编解码不算】,我们使用的缓存数组的大小最好是8,6的公倍数,这样最多是在最后一个缓存数组中需要补位进行编码,然而我们再采用不填充方式编码【好像使用也没有问题】,就万无一失了

以下是使用java代码,当我使用习惯的2的n方1024做缓存数组,解析pdf不能显示,视频和图片不能解析,或者是图片部分显示

一旦我把缓冲数组改成了1200后,所有的编解码都编的非常顺利,没有任何问题,希望这个经验对大家有所帮助,有任何问题请留言一起学习。

package com.ygpx.www.b64;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.Base64;

public class B64 {

    private static final Logger LOG = LoggerFactory.getLogger(B64.class);

    private static int p_mode;

    public static void main(String[] args) {
        // 加密
//        x2B64("C:\\Users\\hgy\\Desktop\\b64", B64Constant.ENCODE);
        // 解密
        x2B64("C:\\Users\\hgy\\Desktop\\b64", B64Constant.DECODE);
    }

    public static void x2B64(String parPath, int mode) {
        p_mode = mode;
        File file = new File(parPath);
        dealFile(file);

    }

    private static void dealFile(File file) {
        if (file.exists()) {
            if (file.isDirectory()) {
                // 递归遍历
                File[] files = file.listFiles();
                for (int i = 0; i < files.length; i++) {
                    dealFile(files[i]);
                }
            } else {
                // 开始转码
                try {
                    startX2B64(file);
                } catch (IOException e) {
                    LOG.error("ygpx_error:[io] {}", e.getMessage());
                    e.printStackTrace();
                }
            }
        } else {
            LOG.error("ygpx_error:[file] The file do not exists!");
        }
    }

    private static void startX2B64(File file) throws IOException {
        String originName = file.getName();
        String parPath = file.getParent();
        String b64Name = null;
        if (p_mode == B64Constant.ENCODE) {
            b64Name = new String(x2B64Encoder(originName), B64Constant.ENCODING_UTF_8);
        } else {
            b64Name = new String(b642XDecoder(originName), B64Constant.ENCODING_UTF_8);
        }

        // 输入
        FileInputStream fis = new FileInputStream(file);
//        FileChannel fisChannel = fis.getChannel();
        // 输出
        FileOutputStream fos = new FileOutputStream(new File(parPath + File.separator + b64Name));
//        BufferedWriter br = new BufferedWriter(new OutputStreamWriter(fos));
//        FileChannel fosChannel = fos.getChannel();
//        ByteBuffer buffer = ByteBuffer.allocate(1024);
        byte[] buf = new byte[1200];
        int i = -1;
        while ((i = fis.read(buf)) != -1) {
            byte[] bs = new byte[i];
            for (int j = 0; j < i; j++) {
                bs[j] = buf[j];
            }
            if (p_mode == B64Constant.ENCODE) {
                byte[] bytes = x2B64Encoder(bs);
                fos.write(bytes);
                fos.flush();
            } else {
                byte[] bytes = b642XDecoder(bs);
                // 使用字节流写解密数据
                fos.write(bytes);
                fos.flush();
            }
        }

    }

    public static byte[] x2B64Encoder(String originStrg) {
        Base64.Encoder encoder = Base64.getEncoder()/*.withoutPadding()*/;
        return encoder.encode(originStrg.getBytes());
    }

    public static byte[] x2B64Encoder(byte[] originBytes) {
        Base64.Encoder encoder = Base64.getEncoder()/*.withoutPadding()*/;
        return encoder.encode(originBytes);
    }

    public static byte[] b642XDecoder(byte[] b64Byte) {
        return Base64.getDecoder().decode(b64Byte);
    }

    public static byte[] b642XDecoder(String b64Strg) {
        return Base64.getDecoder().decode(b64Strg);
    }

}

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

岁月玲珑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值