美文网首页
Java实现Base64加解密方法汇总以及性能比较

Java实现Base64加解密方法汇总以及性能比较

作者: Arison | 来源:发表于2019-01-17 15:09 被阅读8次

    概述

    BASE64 编码是一种常用的字符编码,在很多地方都会用到。但base64不是安全领域下的加密解密算法。能起到安全作用的效果很差,而且很容易破解,他核心作用应该是传输数据的正确性,有些网关或系统只能使用ASCII字符。Base64就是用来将非ASCII字符的数据转换成ASCII字符的一种方法,而且base64特别适合在http,mime协议下快速传输数据。

    Base64 实现方式

    Java实现Base64加解密的方式主要有以下几种:

    1:JDK中的sun.misc套件(在JDK1.6之前,JDK核心类一直没有Base64的实现类,有人建议用Sun/Oracle JDK里面的sun.misc.BASE64Encoder 和 sun.misc.BASE64Decoder,使用它们的优点就是不需要依赖第三方类库,缺点就是可能在未来版本会被删除(用maven编译会发出警告),而且性能不佳,后面会有性能测试。)
    2:第三方扩展包 bouncy castle
    3:第三方扩展包 commons codec
    4:JDK8及更高版本中的 java.util.Base64(推荐:在Java 8在java.util包下面实现了BASE64编解码API,而且性能不俗,API也简单易懂)
    5:JDK6中的DatatypeConverter (JDK1.6中添加了另一个Base64的实现,javax.xml.bind.DatatypeConverter两个静态方法parseBase64Binary 和 printBase64Binary,隐藏在javax.xml.bind包下面,不被很多开发者知道。)
    6:第三方实现Base64的API Google Guava库第二个便是Google Guava库里面的com.google.common.io.BaseEncoding.base64() 这个静态方法;
    7:第三方实现Base64的API net.iharder.Base64第三个是net.iharder.Base64,这个jar包就一个类;
    8:第三方实现Base64的API MigBase64 (最后一个,号称Base64编码速度最快的MigBase64,而且是10年前的实现,到现在是否能保持这个称号,测一测便知道;)

    有关这几种实现方式的性能对比请看:http://www.importnew.com/14961.html

    这里主要讲下第三种和第四种:

    前面做人脸识别的时候,我自己搭建了一个websocket服务器,需要把图片文件转成base64字符串传给硬件,然后再从硬件设备取出白名单所有注册用户的列表信息。刚开始的时候不熟悉Base64加解密有三种BASE64编解码器方式。我用标准的BASE64编码(服务器)与MIME编码(设备)后的图片字符串对接的时候,发现了问题。

    首先,图片文件经过标准BASE64编码和MIME编码后的字符串长得不一样。
    其次,经过MIME编码后的字符串不能按照标准BASE64解码方式转成图片文件。

    Base64三种编解码器

    • Basic编码:是标准的BASE64编码,用于处理常规的需求
    • URL编码:使用下划线替换URL里面的反斜线“/”
    • MIME编码:使用基本的字母数字产生BASE64输出,而且对MIME格式友好:每一行输出不超过76个字符,而且每行以“\r\n”符结束。

    现在以JDK8 java.util.Base64来说明:

    Basic编码:是标准的BASE64编码,用于处理常规的需求

    //编码
    String asB64 = Base64.getEncoder().encodeToString("some string".getBytes("utf-8"));
    System.out.println(asB64);// 输出为: c29tZSBzdHJpbmc=`
    //解码
    byte [] asBytes = Base64.getDecoder().decode("c29tZSBzdHJpbmc=");`
    System.out.println(new String(asBytes,"utf-8"));// 输出为: some string`
    

    URL编码:使用下划线替换URL里面的反斜线“/”

    String urlEncoded = Base64.getUrlEncoder().encodeToString("subjects?abcd".getBytes("utf-8"));
    System.out.println("Using URL Alphabet: "+ urlEncoded);
    // 输出为:
    Using URL Alphabet: c3ViamVjdHM_YWJjZA==
    

    MIME编码:使用基本的字母数字产生BASE64输出,而且对MIME格式友好:每一行输出不超过76个字符,而且每行以“\r\n”符结束。

    StringBuilder sb =new StringBuilder();
    for(int t = 0; t <10; ++t) {
    sb.append(UUID.randomUUID().toString());
    }
    byte [] toEncode = sb.toString().getBytes("utf-8");
    String mimeEncoded = Base64.getMimeEncoder().encodeToString(toEncode);
    System.out.println(mimeEncoded);
    

    其中第三方扩展包 commons codec就是依据MIME编码器来进行编码操作的。可以看它提供的官方API:

    http://commons.apache.org/proper/commons-codec/archives/1.10/apidocs/index.html

    看到这里就恍然大悟了,现在用java.util.Base64 MIME方式来解码commons codec编码的Base64字符串,能顺利的解码成图片文件。

    java.util.Base64 MIME方式来解码

    //base64字符串转图像文件
      public static boolean baseStrToImg(String baseStr, String imgFilePath) {
            if (StringUtils.isBlank(baseStr)) {// 图像数据为空
                return false;
            }
            try {
                // Base64解码  关键采用MIME解码
                byte[] bytes = Base64.getMimeDecoder().decode(baseStr);
                for (int i = 0; i < bytes.length; ++i) {
                    if (bytes[i] < 0) {// 调整异常数据
                        bytes[i] += 256;
                    }
                }
                // 生成jpeg图片
                OutputStream out = new FileOutputStream(imgFilePath);
                out.write(bytes);
                out.flush();
                out.close();
                return true;
            }
            catch (Exception e) {
                return false;
            }
       }
    
    

    java.util.Base64 MIME方式来编码

    //图像文件转base64字符串
     public static String imgToBaseStr(String imgFilePath) {
            InputStream in = null;
            byte[] data = null;
            // 读取图片字节数组
            try {
                in = new FileInputStream(imgFilePath);
                data = new byte[in.available()];
                in.read(data);
                in.close();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            // 对字节数组Base64编码
            return Base64.getMimeEncoder().encodeToString(data); // 返回Base64编码过的字节数组字符
        }
    
    

    参考文献

    原文地址:https://www.yundashi168.com/articles/2019/01/17/1547708559206.html

    相关文章

      网友评论

          本文标题:Java实现Base64加解密方法汇总以及性能比较

          本文链接:https://www.haomeiwen.com/subject/jgeidqtx.html