关于Base64编码(Encode)与解码(Decode)的⼏种⽅式,
这⾥⾯有道道
原创博⽂,欢迎转载,转载时请务必附上博⽂链接,感谢您的尊重。
前⾔
急于现在、⽴刻、马上解决问题的同学,请直接拉到最下⾯的【五、总结】
通过本篇的学习,你将学会Base64的基本概念,优缺点,常⽤的编码、解码⽅法,以及项⽬中的实战使⽤。
更多使⽤Base64编码的原因,以及实际使⽤Demo,请看我另⼀篇博⽂:
更多使⽤Base64的⽅法,以及实战⽤法,请看我另⼀篇博⽂:
⼀、Base64是什么?
Base64是⽹络上最常见的⽤于传输8Bit的编码⽅式之⼀,是⼀种⽤64个字符来表⽰任意数据的⽅法;
Base64编码不仅⽐较简短,同时也具有不可读性,即所编码的数据不会被⼈⽤⾁眼所直接看到,但这种⽅式很初级,很简单;
Base64只是⼀种通过查表的编码算法,不是安全领域下的加解密算法,所以不能单独⽤于加密,即使使⽤⾃定义的编码表也不⾏;
Base64的编码与解码,只是字符到⼆进制与⼆进制到字符的过程,所以特别适⽤于⼩段内容的编码,⽐如http、数字证书签名、Cookie的内容等。
注意,UTF-8和GBK中⽂格式的Base64编码结果是不同的。
⼆、原理
Base64的原理很简单,⾸先,准备⼀个包含64个字符的数组:['A', 'B', 'C', ... 'a', 'b', 'c', ... '0', '1', ... '+', '/']
然后,对⼆进制数据进⾏处理,每3个字节⼀组,⼀共是3x8=24bit,划为4组,每组正好6个bit:
这样我们得到4个数字作为索引,然后查表,获得相应的4个字符,就是编码后的字符串。
所以,Base64编码会把3字节的⼆进制数据编码为4字节的⽂本数据,长度增加33%,好处是编码后的⽂本数据可以在邮件正⽂、⽹页等直接显⽰。
如果要编码的⼆进制数据不是3的倍数,最后会剩下1个或2个字节怎么办?Base64⽤\x00字节在末尾补⾜后,再在编码的末尾加上1个或2个=号,表⽰补了多少字节,解码的时候,会⾃动去掉。
三、Java下Base64的编码与解码
按照出现时间和JAR的不同,⽬前主流有三种⽅式,如下(此处借鉴了前辈经验):
1.sun.misc下的BASE64Encoder和BASE64Decoder
⽤法如下(⽰例):
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class Base64Test {
private static final BASE64Encoder ENCODE_64 = new BASE64Encoder();
private static final BASE64Decoder DECODE_64 = new BASE64Decoder();
@Test
public void sun_misc_base64_T() {
String text = "这是⼀串需要编码的明⽂,可以是URL、图⽚、⽂件或其他。";
try {
// 编码
String encodedToStr = Bytes("UTF-8"));
System.out.println("encodedToStr = " + encodedToStr);
/
/ 解码
String byteToText = new String(DECODE_64.decodeBuffer(encodedToStr), "UTF-8");
System.out.println("byteToText = " + byteToText);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
结果展⽰:
encodedToStr = 6L+Z5piv5LiA5Liy6ZyA6KaB57yW56CB55qE5piO5paH77yM5Y+v5Lul5pivVVJM44CB5Zu+54mH 44CB5paH5Lu25oiW5YW25LuW44CC
byteToText = 这是⼀串需要编码的明⽂,可以是URL、图⽚、⽂件或其他。
优缺点:
这是JDK中⾃带的BASE64⼯具;在线url网址编码解码
但是所提供的Base64功能编码和解码的效率并不太⾼,⽽且在JDK1.9以后就不被维护了。
所以,我们完全不建议再使⽤此⽅法,只作为Base64知识的扩展,重点关注下⾯两种⽅法。
⽤法如下(⽰例):
import dec.binary.Base64;
public class Base64Test {
private static final Base64 BASE_64 = new Base64();
@Test
public void sun_misc_base64_T() {
String text = "这是⼀串需要编码的明⽂,可以是URL、图⽚、⽂件或其他。";
try {
// 编码
String encodedToStr = Bytes("UTF-8"));
System.out.println("encodedToText = " + encodedToStr);
// 解码
String byteToText = new String(BASE_64.decode(encodedToStr), "UTF-8");
System.out.println("byteToText = " + byteToText);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
结果展⽰:
优缺点:
与sun.misc⽅式⽐较,它的效率更⾼,代码更简洁;
与dec.binary⽅式⽐较,它所有的JDK版本都⽀持,不只局限于JDK1.8以上。
3.java.util下的Base64
这是JDK1.8的java.util套件中新增的类,⽬的就是⾼效的处理Base64的编码与解码,⽤法如下(⽰例):
import java.util.Base64;
public class Base64Test {
private static final Base64.Decoder DECODE_64 = Decoder();
private static final Base64.Encoder ENCODE_64 = Encoder();
@Test
public void sun_misc_base64_T() {
String text = "这是⼀串需要编码的明⽂,可以是URL、图⽚、⽂件或其他。";
try {
// 编码
String encodedToStr = Bytes("UTF-8"));
System.out.println("encodedToStr = " + encodedToStr);
// 解码
String byteToText = new String(DECODE_64.decode(encodedToStr), "UTF-8");
System.out.println("byteToText = " + byteToText);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
结果展⽰:
优缺点:
java.util提供的Base64拥有更好的效能,实际测试编码与解码速度的话,⽐sun.misc套件提供的还要快⾄少11倍,⽐
dec.binary提供的还要快⾄少3倍;
但是,需要JDK1.8以后的版本才⽀持。
四、Python下Base64的编码与解码
Python内置的Base64可以直接进⾏base64的编解码:
>>> import base64
>>> base64.b64encode(b'binary\x00string')
b'YmluYXJ5AHN0cmluZw=='
>>> base64.b64decode(b'YmluYXJ5AHN0cmluZw==')
b'binary\x00string'
由于标准的Base64编码后可能出现字符+和/,在URL中就不能直接作为参数,所以⼜有⼀种"url safe"的base64编码,其实就是把字符+和/分别变成-和_:
>>> base64.b64encode(b'i\xb7\x1d\xfb\xef\xff')
b'abcd++//'
>>> base64.urlsafe_b64encode(b'i\xb7\x1d\xfb\xef\xff')
b'abcd--__'
>>> base64.urlsafe_b64decode('abcd--__')
b'i\xb7\x1d\xfb\xef\xff'
五、总结
感觉Python⾥⾯没太多需要注意的,所以下⾯的总结只针对Java:
如果项⽬的JDK版本⼩于1.8,请使⽤dec.binary.Base64;
如果项⽬的JDK版本⼤于1.8,请使⽤java.util.Base64;
使⽤dec.binary.Base64时,要选择与项⽬JDK相符的JAR包,否则实现不了效果;
java.util.Base64与dec.binary.Base64包冲突,不能同时存在⼀个类中;
注意,UTF-8和GBK中⽂格式的Base64编码结果是不同的。
我是⼀名⼩⽩程序员,您的点赞、评论和关注,是我不懈创作的动⼒!!
学⽆⽌境,⽓有浩然,让我们⼀起加油,乘风破浪,江湖有缘再见。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论