Java中的Base64详解

详解Java中的Base64原理跟用法

简介

​ Base64编码,是我们程序开发中经常使用到的编码方法。它是一种基于用64个可打印字符来表示二进制数据的表示方法。它通常用作存储、传输一些二进制数据编码方法, 也是MIME(多用途互联网邮件扩展,主要用作电子邮件标准)中一种可打印字符表示二进制数据的常见编码方法。它其实只是定义用可打印字符传输内容一种方法,并不会产生新的字符集。严格来说Base64并不是一种加密/解密算法,而是一种编码方式。Base64不生成密钥,通过Base64编码后的密文就可以直接“翻译”为明文,但是可以通过向明文中添加混淆字符来达到加密的效果。

Base64实现转换原理

​ 它是用64个可打印字符表示二进制所有数据方法。由于2的6次方等于64,所以可以用每6个位元为一个单元,对应某个可打印字符。我们知道三个字节有24个位元,就可以刚好对应于4个Base64单元,即3个字节需要用4个Base64的可打印字符来表示。在Base64中的可打印字符包括字母A-Z、a-z、数字0-9 ,这样共有62个字符,此外两个可打印符号在不同的系统中一般有所不同。但是,我们经常所说的Base64另外2个字符是:“+/”。这64个字符,所对应表如下:

img

​ 转换的时候,将三个byte的数据,先后放入一个24bit的缓冲区中,先来的byte占高位。数据不足3byte的话,于缓冲区中剩下的bit用0补足。然后,每次取出6个bit,按照其值选择
**ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/**中的字符作为编码后的输出。不断进行,直到全部输入数据转换完成。

如果最后剩下两个输入数据,在编码结果后加1个“=”;如果最后剩下一个输入数据,编码结果后加2个“=”;如果没有剩下任何数据,就什么都不要加,这样才可以保证资料还原的正确性。

编码后的数据比原始数据略长,为原来的4/3。无论什么样的字符都会全部被编码,因此不像Quoted-printable编码,还保留部分可打印字符。所以,它的可读性不如Quoted-printable编码!

img
​ M的Ascii码是77,前六位对应值为19,对应base64字符是T,如此类推。其它字符编码就可以自动转换得到!我们看看另外不是刚好是3个字节的情况!
img

代码示例

import java.io.UnsupportedEncodingException;
 
/**
 * @Description 演示Base64的加密、解密
 * @author ShengLiu
 * @date 2018/6/20
 */
public class Base64Demo {
    
    
 
    public static void main(String[] args) {
    
    
        //加密
        System.out.println(Base64Demo.getBase64Encode("Hello,World!"));
        //解密
        System.out.println(Base64Demo.getBase64Decode("SGVsbG9Xb3JsZA=="));
    }
 
    public static String getBase64Encode(String str) {
    
    
        if (str == null || "".equals(str)) {
    
    
            return "";
        }
        try {
    
    
            byte[] bt = str.getBytes("UTF-8");
            str = String.valueOf(Base64.encode(bt));
        } catch (UnsupportedEncodingException e) {
    
    
            e.printStackTrace();
        }
        return str;
    }
 
    public static String getBase64Decode(String str) {
    
    
        if (str == null || "".equals(str)) {
    
    
            return "";
        }
        char[] ch = str.toCharArray();
        byte[] bt = Base64.decode(String.valueOf(ch));
        try {
    
    
            str = new String(bt,"UTF-8");
        } catch (UnsupportedEncodingException e) {
    
    
            e.printStackTrace();
        }
        return str;
    }
}

输出结果

SGVsbG/vvIxXb3JsZCE=
HelloWorld

代码示例

package com.test.demo;
 
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
 
import java.io.UnsupportedEncodingException;
 
/**
 * @Description Base64的加密、解密测试
 * @author ShengLiu
 * @date 2018/6/20
 */
public class Base64 {
    
    
 
    public static void main(String[] args) {
    
    
        System.out.println(Base64.getBase64Encode("你们好!!!"));
        System.out.println(Base64.getBase64Decode("5L2g5Lus5aW977yB77yB77yB"));
    }
 
    // 加密
    public static String getBase64Encode(String str) {
    
    
        byte[] b = null;
        String s = null;
        try {
    
    
            b = str.getBytes("utf-8");
        } catch (UnsupportedEncodingException e) {
    
    
            e.printStackTrace();
        }
        if (b != null) {
    
    
            s = new BASE64Encoder().encode(b);
        }
        return s;
    }
 
    // 解密
    public static String getBase64Decode(String s) {
    
    
        byte[] b = null;
        String result = null;
        if (s != null) {
    
    
            BASE64Decoder decoder = new BASE64Decoder();
            try {
    
    
                b = decoder.decodeBuffer(s);
                result = new String(b, "utf-8");
            } catch (Exception e) {
    
    
                e.printStackTrace();
            }
        }
        return result;
    }
}

输出结果

5L2g5Lus5aW977yB77yB77yB
你们好!!!


sun.misc.BASE64Encoder详解

(一)、BASE64编码规则及JAVA中的使用

1、编码规则:

Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式。
例如字符串“张3” :
11010101 11000101 00110011
用十进制表示即为:53 34 20 51
这个并不是最终的结果,还需要根据Base64的编码表查询出转换后值。
下面就是BASE64编码表:

Table 1: The Base64 Alphabet   
Value Encoding Value Encoding Value Encoding Value Encoding  
0 A     17 R     34 i     51 z  
1 B     18 S     35 j     52 0  
2 C     19 T     36 k     53 1  
3 D     20 U     37 l     54 2  
4 E     21 V     38 m     55 3  
5 F     22 W     39 n     56 4  
6 G     23 X     40 o     57 5  
7 H     24 Y     41 p     58 6  
8 I     25 Z     42 q     59 7  
9 J     26 a     43 r     60 8  
10 K    27 b     44 s     61 9  
11 L    28 c     45 t     62 +  
12 M    29 d     46 u     63 /  
13 N    30 e     47 v     (pad) =  
14 O    31 f     48 w   
15 P    32 g     49 x  
16 Q    33 h     50 y 
  1. 以上一共是64个编码,这也是Base64名称的由来。
  2. 编码的编号(1-64)对应的是得出的新字节的十进制值。因此,上例中字符串“张3”经过编码后就成了字符串“1iUz”了。
  3. 若要对只有两个字节的字符串进行编码,如“张”,则在其编码结果的后面加“=”,即“1iU=”。
  4. 若要对只有一个字节的字符串进行编码,如“3”,则在其编码结果的后面加“”,即“z”。

2、编码和解码

在JAVA中要实现Base64的编码和解码是非常容易的,因为JDK中已经有提供有现成的类:
编码:

String src ="BASE64编码测试";  
sun.misc.BASE64Encoder en = new sun.misc.BASE64Encoder(); 
String encodeStr = en.encode(src.getBytes());     

解码:

 sun.misc.BASE64Decoder dec = newsun.misc.BASE64Decoder(); 
 byte[] data = dec.decodeBuffer(decodeStr); 

更多知识点参考请点击这里

filename = "=?UTF-8?B?"+new BASE64Encoder().encoder(filename.getBytes("utf-8"))+"?=";

img

BASE64Encoder 加密和解密

public class B64Demo {
    
    
    public static String getBASE64(String s) {
    
      
        if (s == null)  
            return null;  
        return (new sun.misc.BASE64Encoder()).encode(s.getBytes());  
    }  
    // 将 BASE64 编码的字符串 s 进行解码
    public static String getFromBASE64(String s) {
    
      
        if (s == null)  
            return null;  
        sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();  
        try {
    
      
            byte[] b = decoder.decodeBuffer(s);  
            return new String(b);  
        } catch (Exception e) {
    
      
            return null;  
        }  
    }  
    // 将 BASE64 编码的字符串 s 进行加密,即对字符串进行三次的BASE64编码
    public static String encryption(Object obj){
    
    
        return B64Demo.getBASE64(B64Demo.getBASE64(B64Demo.getBASE64((String)obj)));
    }
    // 将 BASE64 编码的字符串 s 进行解密,即对字符串进行三次的BASE64解码
    public static String decryption(String 3b64){
    
    
        return B64Demo.getFromBASE64(B64Demo.getFromBASE64(B64Demo.getFromBASE64(3b64)));
    }
    public static void main(String[] args) {
    
    
          String a = encryption("100000.89".toString());
          System.out.println(a);//加密
          System.out.println(decryption(a));//解密
    }
}


一、jdk1.8下的 BASE64Encoder 和 BASE64Decoder(JDK9开始已移除):

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class test {
    
    
    public static void main(String[] args) throws Exception {
    
    

        String str = "hello word";
        BASE64Encoder base64Encoder = new BASE64Encoder();
        // JDK1.8 BASE64Encoder 加密
        String encode = base64Encoder.encode(str.getBytes());
        System.out.println(encode);

        BASE64Decoder base64Decoder = new BASE64Decoder();
        // JDK1.8 BASE64Decoder 解密
        byte[] bytes = base64Decoder.decodeBuffer(encode);
        String res = new String(bytes);
        System.out.println(res);
    }
}

二、推荐使用Base64:

package com.lmp.utils;

import java.util.Base64;

public class test {
    
    
    public static void main(String[] args) throws Exception {
    
    

        String str = "hello word";
        // JDK1.8 Base64加密
        String encode = Base64.getEncoder().encodeToString(str.getBytes());
        System.out.println(encode);

        // JDK1.8 Base64解密
        byte[] bytes = Base64.getDecoder().decode(encode);
        String res = new String(bytes);
        System.out.println(res);
    }

}

猜你喜欢

转载自blog.csdn.net/qq_43842093/article/details/127328971
今日推荐