Base64编码

229 阅读2分钟

在早期由于历史问题,电子邮件只允许ASCII码字符。如果要传输一封带有非ASCII码字符的电子邮件就会遇到困难了。基于这个原因产生了Base64编码。
Base64是一种基于64个字符的编码算法,是一组二进制到文本的编码方案,它将二进制数据转换为可打印字符序列。经Base64编码后的字符串的字符数是以4为单位的整数倍。

Base64字符映射表 为了能在http请求中以get方式传递二进制数据,由Base64算法衍生出了Url Base64算法。 Base64算法可逆,字符映射表充当了密钥。尽管如此,Base64算法不能叫作加密算法。Base64算法公开,这一点与柯克霍夫原则并无违背,但充当密钥的字符映射表是公开的,直接违反了柯克霍夫原则。
补:GB2312、GBK用两个字节表示一个汉字,UTF8用三个字节表示一个汉字。
JDK、commons-codec和bouncy-castle-bc都提供了Base64算法。
1.JDK的Base64算法:

package com.fulcrum.encrypt;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class JdkBase64Demo {
    public static void main(String[] args) {
        System.out.println(Base64.getEncoder().encodeToString("A".getBytes(StandardCharsets.UTF_8)));
        System.out.println(Base64.getEncoder().encodeToString("A".getBytes(Charset.forName("GBK"))));
        System.out.println(Base64.getEncoder().encodeToString("A".getBytes(Charset.forName("GB2312"))));
        System.out.println("=========");
        System.out.println(Base64.getEncoder().encodeToString("密".getBytes(StandardCharsets.UTF_8)));
        System.out.println(Base64.getEncoder().encodeToString("密".getBytes(Charset.forName("GBK"))));
        System.out.println(Base64.getEncoder().encodeToString("密".getBytes(Charset.forName("GB2312"))));
        System.out.println("=========");
        String str = "开放自由包容";
        String base64Str = Base64.getEncoder().encodeToString(str.getBytes(StandardCharsets.UTF_8));
        System.out.println("'开放自由包容'经过Base64编码后:"+base64Str);
        boolean flag = str.equals(new String(Base64.getDecoder().decode(base64Str)));
        System.out.println("Base64编码再解码后是否与原字符串相等:"+flag);
    }
}

控制台输出

2.commons-codec的Base64算法:

package com.fulcrum.encrypt;

import org.apache.commons.codec.binary.Base64;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

public class CommonsCodecBase64Demo {
    public static void main(String[] args) {
        System.out.println(Base64.encodeBase64String("A".getBytes(StandardCharsets.UTF_8)));
        System.out.println(Base64.encodeBase64String("A".getBytes(Charset.forName("GBK"))));
        System.out.println(Base64.encodeBase64String("A".getBytes(Charset.forName("GB2312"))));
        System.out.println("=========");
        System.out.println(Base64.encodeBase64String("密".getBytes(StandardCharsets.UTF_8)));
        System.out.println(Base64.encodeBase64String("密".getBytes(Charset.forName("GBK"))));
        System.out.println(Base64.encodeBase64String("密".getBytes(Charset.forName("GB2312"))));
        System.out.println("=========");
        String str = "开放自由包容";
        String base64Str = Base64.encodeBase64String(str.getBytes(StandardCharsets.UTF_8));
        System.out.println("'开放自由包容'经过Base64编码后:"+base64Str);
        boolean flag = str.equals(new String(Base64.decodeBase64(base64Str)));
        System.out.println("Base64编码再解码后是否与原字符串相等:"+flag);
    }
}

控制台输出

3.bouncy-castle-bc的Base64算法:

package com.fulcrum.encrypt;

import org.bouncycastle.util.encoders.Base64;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

public class BouncyCastleBase64Demo {
    public static void main(String[] args) {
        System.out.println(Base64.toBase64String("A".getBytes(StandardCharsets.UTF_8)));
        System.out.println(Base64.toBase64String("A".getBytes(Charset.forName("GBK"))));
        System.out.println(Base64.toBase64String("A".getBytes(Charset.forName("GB2312"))));
        System.out.println("=========");
        System.out.println(Base64.toBase64String("密".getBytes(StandardCharsets.UTF_8)));
        System.out.println(Base64.toBase64String("密".getBytes(Charset.forName("GBK"))));
        System.out.println(Base64.toBase64String("密".getBytes(Charset.forName("GB2312"))));
        System.out.println("=========");
        String str = "开放自由包容";
        String base64Str = Base64.toBase64String(str.getBytes(StandardCharsets.UTF_8));
        System.out.println("'开放自由包容'经过Base64编码后:"+base64Str);
        boolean flag = str.equals(new String(Base64.decode(base64Str)));
        System.out.println("Base64编码再解码后是否与原字符串相等:"+flag);
    }
}

控制台输出