Base64编码的原理与常用实现
這篇主要是為了后面好介紹加密算法,做的鋪墊。
這個(gè)是基礎(chǔ),什么是一個(gè)程序員的涵養(yǎng),這些基礎(chǔ)就是涵養(yǎng)。
平時(shí)可能用不到,但必須得會(huì)。
如果連這個(gè)原理都說(shuō)不上來(lái),就別玩王者榮耀絕地求生英雄聯(lián)盟和平精英了,該好好補(bǔ)補(bǔ)了。
Base64編碼定義
Base64編碼是基于64個(gè)字符的編碼方式。
所有的二進(jìn)制數(shù)據(jù)都可以用這64個(gè)編碼來(lái)表示。
怎么編碼,64個(gè)字符有哪些,是基于一個(gè)規(guī)范的:RFC2045
Base64編碼特點(diǎn)
Base64編碼是可逆的。
編碼后的結(jié)果,沒(méi)有任何可讀性。
適用性廣泛,任何能轉(zhuǎn)成二進(jìn)制數(shù)的數(shù)據(jù)都能Base64編碼。
Base64編碼原理
Base64編碼入?yún)⑹嵌M(jìn)制數(shù)
首先有個(gè)編碼對(duì)照表,索引從0到63總共64個(gè),對(duì)應(yīng)著(A-Z)加(a-z)加(0-9)加(+)加(/)剛好64個(gè)字符。
編碼有以下幾步:
1、將數(shù)據(jù)拆成若干組,每組3個(gè)字節(jié),即24位。
2、每組數(shù)據(jù)24位進(jìn)行重組,分為4部分,那么每部分就是6位。
3、將每部分的高位補(bǔ)兩個(gè)0,那么每部分都成8位了,即一個(gè)字節(jié)。此時(shí)這個(gè)組總共就是4個(gè)字節(jié)。
4、將每個(gè)字節(jié)的值換成10進(jìn)制,由于高兩位都是0,所以該字節(jié)的十進(jìn)制數(shù),最大就是63,最小是0,正好和上面的64個(gè)編碼表的索引對(duì)上,然后得到對(duì)應(yīng)字符。合起來(lái)就是最終編碼的值。
如果數(shù)據(jù)的總字節(jié)數(shù),不是3的倍數(shù),那么就存在最后一組不夠3個(gè)字節(jié)。這種情況,就還是按照上面的編碼規(guī)則繼續(xù)編(字節(jié)換成位,每6位高位補(bǔ)兩個(gè)0變成一個(gè)字節(jié))
情況1:
最后一組只有兩個(gè)字節(jié),那就是16位,
前6位,高位補(bǔ)兩個(gè)0 ,變成一個(gè)字節(jié),對(duì)照表拿到對(duì)應(yīng)的第一個(gè)字符;
中間6位,高位補(bǔ)兩個(gè)0 ,變成一個(gè)字節(jié),對(duì)照表拿到對(duì)應(yīng)的第二個(gè)字符;
后4位,高位補(bǔ)4個(gè)0,變成一個(gè)字節(jié),對(duì)照表拿到對(duì)應(yīng)的第三個(gè)字符;
第四個(gè)字符默認(rèn)用=代替。
情況2
最后一組只有一個(gè)字節(jié),那就是8位,
前6位,高位補(bǔ)兩個(gè)0 ,變成一個(gè)字節(jié),對(duì)照表拿到對(duì)應(yīng)的第一個(gè)字符;
后2位,高位補(bǔ)6個(gè)0,變成一個(gè)字節(jié),對(duì)照表拿到對(duì)應(yīng)的第二個(gè)字符;
第三個(gè)字符和第四個(gè)字符默認(rèn)都用=代替。
這也就是為什么,有時(shí)候看到的編碼結(jié)果,結(jié)尾會(huì)有=或者==,就是這種不夠的情況。
另外,每76個(gè)字符加一個(gè)換行符,這個(gè)是規(guī)定。
解碼就反過(guò)來(lái)操作,是不是很簡(jiǎn)單。不考慮性能的話,完全可以自己嘗試寫一個(gè)Base64編碼工具類玩玩。
Base64衍生編碼方式
Base 16
Base 32
Url Base64
看過(guò)Base64的原理,Base16和Base32的就類似了,都是拆字節(jié),然后高位補(bǔ)0,使得新的字節(jié),最大是16或者32,然后照著表找對(duì)應(yīng)字符。
url Base64的出現(xiàn),是因?yàn)闃?biāo)準(zhǔn)的Base64,最后兩個(gè)字符+/在url中不能作為參數(shù),所以u(píng)rl Base64主要改動(dòng)就是把這兩個(gè)字符換成了-和_。
Base64編碼常見實(shí)現(xiàn)
Base64的實(shí)現(xiàn)有很多種,常見的兩個(gè):JDK的和Apache的
JDK的Base64
import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import java.io.IOException;public class Base64Test {public static void main(String[] args) throws IOException {String str = "hello word";BASE64Encoder base64Encoder = new BASE64Encoder();// JDK Base64加密String encode = base64Encoder.encode(str.getBytes());System.out.println(encode);BASE64Decoder base64Decoder = new BASE64Decoder();// JDK Base64解密byte[] bytes = base64Decoder.decodeBuffer(encode);String res = new String(bytes);System.out.println(res);} }Apache的Base64
引入pom依賴:
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec --> <dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.14</version> </dependency> import org.apache.commons.codec.binary.Base64;public class ApacheBase64Test {public static void main(String[] args) {String str = "hello word";// Apache Base64加密byte[] encodeBytes = Base64.encodeBase64(str.getBytes());System.out.println(new String(encodeBytes));// Apache Base64解密byte[] decodeBytes = Base64.decodeBase64(encodeBytes);System.out.println(new String(decodeBytes));} }當(dāng)然,上面兩個(gè)的結(jié)果都是:
aGVsbG8gd29yZA== hello word總結(jié)
以上是生活随笔為你收集整理的Base64编码的原理与常用实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java多态可以传匿名对象吗_Java复
- 下一篇: 电子数字计算机最早应用于哪个领域,201