Java base64加密解密

参考:

https://www.cnblogs.com/luguo3000/p/3940197.html

https://blog.csdn.net/jiahao1186/article/details/83661862

https://www.cnblogs.com/alter888/p/9140732.html

 

 

 

 

从原理上搞定编码-- Base64编码

开发者对Base64编码肯定很熟悉,是否对它有很清晰的认识就不一定了。实际上Base64已经简单到不能再简单了,如果对它的理解还是模棱两可实在不应该。大概介绍一下Base64的相关内容,花几分钟时间就可以彻底理解它。文章下边贴了一个Base64的编解码器,方便阅读文章的同时来实验。

  一. Base64编码由来

  为什么会有Base64编码呢?因为有些网络传送渠道并不支持所有的字节,例如传统的邮件只支持可见字符的传送,像ASCII码的控制字符就不能通过邮件传送。这样用途就受到了很大的限制,比如图片二进制流的每个字节不可能全部是可见字符,所以就传送不了。最好的方法就是在不改变传统协议的情况下,做一种扩展方案来支持二进制文件的传送。把不可打印的字符也能用可打印字符来表示,问题就解决了。Base64编码应运而生,Base64就是一种基于64个可打印字符来表示二进制数据的表示方法。

 

  二. Base64编码原理

  看一下Base64的索引表,字符选用了"A-Z、a-z、0-9、+、/" 64个可打印字符。数值代表字符的索引,这个是标准Base64协议规定的,不能更改。64个字符用6个bit位就可以全部表示,一个字节有8个bit位,剩下两个bit就浪费掉了,这样就不得不牺牲一部分空间了。这里需要弄明白的就是一个Base64字符是8个bit,但是有效部分只有右边的6个bit,左边两个永远是0。

  那么怎么用6个有效bit来表示传统字符的8个bit呢?8和6的最小公倍数是24,也就是说3个传统字节可以由4个Base64字符来表示,保证有效位数是一样的,这样就多了1/3的字节数来弥补Base64只有6个有效bit的不足。你也可以说用两个Base64字符也能表示一个传统字符,但是采用最小公倍数的方案其实是最减少浪费的。结合下边的图比较容易理解。Man是三个字符,一共24个有效bit,只好用4个Base64字符来凑齐24个有效位。红框表示的是对应的Base64,6个有效位转化成相应的索引值再对应Base64字符表,查出"Man"对应的Base64字符是"TWFU"。说到这里有个原则不知道你发现了没有,要转换成Base64的最小单位就是三个字节,对一个字符串来说每次都是三个字节三个字节的转换,对应的是Base64的四个字节。这个搞清楚了其实就差不多了。

         

  但是转换到最后你发现不够三个字节了怎么办呢?愿望终于实现了,我们可以用两个Base64来表示一个字符或用三个Base64表示两个字符,像下图的A对应的第二个Base64的二进制位只有两个,把后边的四个补0就是了。所以A对应的Base64字符就是QQ。上边已经说过了,原则是Base64字符的最小单位是四个字符一组,那这才两个字符,后边补两个"="吧。其实不用"="也不耽误解码,之所以用"=",可能是考虑到多段编码后的Base64字符串拼起来也不会引起混淆。由此可见Base64字符串只可能最后出现一个或两个"=",中间是不可能出现"="的。下图中字符"BC"的编码过程也是一样的。

  三. 总结  

  说起Base64编码可能有些奇怪,因为大多数的编码都是由字符转化成二进制的过程,而从二进制转成字符的过程称为解码。而Base64的概念就恰好反了,由二进制转到字符称为编码,由字符到二进制称为解码

  Base64编码主要用在传输、存储、表示二进制等领域,还可以用来加密,但是这种加密比较简单,只是一眼看上去不知道什么内容罢了,当然也可以对Base64的字符序列进行定制来进行加密。

  Base64编码是从二进制到字符的过程,像一些中文字符用不同的编码转为二进制时,产生的二进制是不一样的,所以最终产生的Base64字符也不一样。例如"上网"对应utf-8格式的Base64编码是"5LiK572R",对应GB2312格式的Base64编码是"yc/N+A=="。

 

文章参考自 "维基百科-Base64"

 

 

 

 

 

 

Java base64加密解密 两种实现方式

1、为什么要使用Base 64

    Base 64主要用途不是加密,而是把一些二进制数转成普通字符,方便在网络上传输。 由于一些二进制字符在传输协议中属于

控制字符,不能直接传送,所以需要转换一下才可以。由于某些系统中只能使用ASCII字符,Base64就是用来将非ASCII字符的数

据转换成ASCII字符的一种方法,Base64特别适合在http,mime协议下快速传输数据。比如网络中图片的传输。

     Base64,并非安全领域下的加密解密算法。虽然经常遇到所谓的base64的加密解密。但base64只能算是一个编码算法,对数

据内容进行编码来适合传输。虽然base64编码过后原文也变成不能看到的字符格式,但是方式初级又简单。

2、Base 64 原理

        Base64编码方法,要求把每三个8Bit的字节转换为四个6Bit的字节,其中,转换之后的这四个字节中每6个有效bit为是有效

数据,空余的那两个 bit用0补上成为一个字节。因此Base64所造成数据冗余不是很严重,Base64是当今比较流行的编码方法,

因为它编起来速度快而且简单。


 举个例子,有三个字节的原始数据:aaaaaabb bbbbccccc ccdddddd(这里每个字母表示一个bit位)
 那么编码之后会变成:      00aaaaaa 00bbbbbb 00cccccc 00dddddd

所以可以看出base64编码简单,虽然编码后不是明文,看不出原文,但是解码也很简单

2、Base64加密解密的实现方式:两种

package com.liuxd;
 
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
 
import java.util.Base64;
 
/**
 * Created by Liuxd on 2018-11-02.
 */
public class TestString {
 
 
    public static void main(String[] args) throws Exception {
        String str = "青锋剑,偃月刀";
 
        base64(str);
 
        enAndDeCode(str);
 
    }
 
 
    /**
     * Base64
     *
     */
    public static void base64(String str) {
        byte[] bytes = str.getBytes();
 
        //Base64 加密
        String encoded = Base64.getEncoder().encodeToString(bytes);
        System.out.println("Base 64 加密后:" + encoded);
 
        //Base64 解密
        byte[] decoded = Base64.getDecoder().decode(encoded);
 
        String decodeStr = new String(decoded);
        System.out.println("Base 64 解密后:" + decodeStr);
 
        System.out.println();
 
 
    }
 
    /**
     * BASE64加密解密
     */
    public static void enAndDeCode(String str) throws Exception {
        String data = encryptBASE64(str.getBytes());
        System.out.println("sun.misc.BASE64 加密后:" + data);
 
        byte[] byteArray = decryptBASE64(data);
        System.out.println("sun.misc.BASE64 解密后:" + new String(byteArray));
    }
 
    /**
     * BASE64解密
     * @throws Exception
     */
    public static byte[] decryptBASE64(String key) throws Exception {
        return (new BASE64Decoder()).decodeBuffer(key);
    }
 
    /**
     * BASE64加密
     */
    public static String encryptBASE64(byte[] key) throws Exception {
        return (new BASE64Encoder()).encodeBuffer(key);
    }
}

 

输出结果:

Base 64 加密后:6Z2S6ZSL5YmR77yM5YGD5pyI5YiA
Base 64 解密后:青锋剑,偃月刀

sun.misc.BASE64 加密后:6Z2S6ZSL5YmR77yM5YGD5pyI5YiA

sun.misc.BASE64 解密后:青锋剑,偃月刀

 

 

 

 

 

 

Java如何进行Base64的编码(Encode)与解码(Decode)

Base64是一种能将任意Binary资料用64种字元组合成字串的方法,而这个Binary资料和字串资料彼此之间是可以互相转换的,十分方便。在实际应用上,Base64除了能将Binary资料可视化之外,也常用来表示字串加密过后的内容。如果要使用Java 程式语言来实作Base64的编码与解码功能,可以参考本篇文章的作法。

早期作法

早期在Java上做Base64的编码与解码,会使用到JDK里sun.misc套件下的BASE64Encoder和BASE64Decoder这两个类别,用法如下:

复制代码
final BASE64Encoder encoder = new BASE64Encoder();
final BASE64Decoder decoder = new BASE64Decoder();
final String text = "字串文字";
final byte[] textByte = text.getBytes("UTF-8");
//编码
final String encodedText = encoder.encode(textByte);
System.out.println(encodedText);
//解码
System.out.println(new String(decoder.decodeBuffer(encodedText), "UTF-8"));

final BASE64Encoder encoder = new BASE64Encoder();
final BASE64Decoder decoder = new BASE64Decoder();
final String text = "字串文字";
final byte[] textByte = text.getBytes("UTF-8");
//编码
final String encodedText = encoder.encode(textByte);
System.out.println(encodedText);

//解码
System.out.println(new String(decoder.decodeBuffer(encodedText), "UTF-8"));
复制代码

 

 

从以上程式可以发现,在Java用Base64一点都不难,不用几行程式码就解决了!只是这个sun.mis c套件所提供的Base64功能,编码和解码的效率并不太好,而且在以后的Java版本可能就不被支援了,完全不建议使用。

Apache Commons Codec作法

Apache Commons Codec有提供Base64的编码与解码功能,会使用到org.apache.commons.codec.binary套件下的Base64类别,用法如下:

复制代码
final Base64 base64 = new Base64();
final String text = "字串文字";
final byte[] textByte = text.getBytes("UTF-8");
//编码
final String encodedText = base64.encodeToString(textByte);
System.out.println(encodedText);
//解码
System.out.println(new String(base64.decode(encodedText), "UTF-8"));

final Base64 base64 = new Base64();
final String text = "字串文字";
final byte[] textByte = text.getBytes("UTF-8");
//编码
final String encodedText = base64.encodeToString(textByte);
System.out.println(encodedText);
//解码
System.out.println(new String(base64.decode(encodedText), "UTF-8"));
复制代码

 

以上的程式码看起来又比早期用sun.mis c套件还要更精简,效能实际执行起来也快了不少。缺点是需要引用Apache Commons Codec,很麻烦。

Java 8之后的作法

Java 8的java.util套件中,新增了Base64的类别,可以用来处理Base64的编码与解码,用法如下:

复制代码
final Base64.Decoder decoder = Base64.getDecoder();
final Base64.Encoder encoder = Base64.getEncoder();
final String text = "字串文字";
final byte[] textByte = text.getBytes("UTF-8");
//编码
final String encodedText = encoder.encodeToString(textByte);
System.out.println(encodedText);
//解码
System.out.println(new String(decoder.decode(encodedText), "UTF-8"));

final Base64.Decoder decoder = Base64.getDecoder();
final Base64.Encoder encoder = Base64.getEncoder();
final String text = "字串文字";
final byte[] textByte = text.getBytes("UTF-8");
//编码
final String encodedText = encoder.encodeToString(textByte);
System.out.println(encodedText);
//解码
System.out.println(new String(decoder.decode(encodedText), "UTF-8"));
复制代码

与sun.mis c套件和Apache Commons Codec所提供的Base64编解码器来比较的话,Java 8提供的Base64拥有更好的效能。实际测试编码与解码速度的话,Java 8提供的Base64,要比sun.mis c套件提供的还要快至少11倍,比Apache Commons Codec提供的还要快至少3倍。因此在Java上若要使用Base64,这个Java 8底下的java .util套件所提供的Base64类别绝对是首选!

 
 

 

posted on 2020-11-29 21:42  秦羽的思考  阅读(5555)  评论(0编辑  收藏  举报