理解Base64编码及实现编解码Base64
-前言-
上前幾篇博客做圖集分解的時(shí)候Image對(duì)象生成的時(shí)候,不是使用的直接用二進(jìn)制數(shù)據(jù)生成的圖像數(shù)據(jù),而是使用的轉(zhuǎn)化后的base64數(shù)據(jù)來(lái)生成的。本片博客就讓我們來(lái)了解下Base64及寫一個(gè)編解碼器。
-正文-
base64編碼格式是一種可以由文本編輯器打開查看的編碼格式,與二進(jìn)制不同,base64之所有稱為64,也是因?yàn)槲覀円成涞亩M(jìn)制數(shù)據(jù)是在一個(gè)64長(zhǎng)度的字符集中映射出來(lái)的。base64最終生成的其實(shí)就是一長(zhǎng)串字符串。因此Base64是一種用64個(gè)字符來(lái)表示任意二進(jìn)制數(shù)據(jù)的方法。
下面是base64的字符集:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=字節(jié)、位
位是計(jì)算機(jī)存儲(chǔ)單元最小單位,一個(gè)位表示一個(gè)0或者一個(gè)1,一字節(jié)有8位。
二進(jìn)制與Base64的轉(zhuǎn)換關(guān)系
如上圖所示,當(dāng)數(shù)據(jù)剛好3個(gè)字節(jié)的時(shí)候使用4個(gè)字符去表示這3個(gè)字節(jié),它們的比例為3:4,這就意味著基于base64編碼的文本數(shù)據(jù)要比基于二進(jìn)制表示的數(shù)據(jù)要多33%,原本3個(gè)字節(jié)可以表示的數(shù)據(jù)我們用base64去表示就會(huì)需要4個(gè)字節(jié)去表示。
因此base64的優(yōu)點(diǎn)就是它的可讀性,易用性。缺點(diǎn)就是比原始二進(jìn)制數(shù)據(jù)使用了更多空間去表示數(shù)據(jù)。
上面說(shuō)的比例3:4可以使用4個(gè)字節(jié)去生成base64字符串,當(dāng)原始二進(jìn)制數(shù)據(jù)不是3的倍數(shù)時(shí)也同樣可以表示。
當(dāng)原始數(shù)據(jù)不是字節(jié)數(shù)不是3的倍數(shù)時(shí)
原始數(shù)據(jù)不可能剛剛好3的倍數(shù),假設(shè)現(xiàn)在我們的原始數(shù)據(jù)是2個(gè)字節(jié),也就是16位,換算成base64要囊括這16位數(shù)據(jù)需要3 * 6 =18位數(shù)據(jù)來(lái)表示,就多余了2位,多出的數(shù)據(jù)我們就可以使用”=“來(lái)表示,也就是上面字符集中的最后一個(gè)符號(hào)。當(dāng)多出2位的時(shí)候就使用兩個(gè)”=“來(lái)補(bǔ)足。
二進(jìn)制數(shù)據(jù)與base64的轉(zhuǎn)換
我們以字符”A“的轉(zhuǎn)換舉例來(lái)看看是如何轉(zhuǎn)換的。
首先A的Unicode碼為65,二進(jìn)制表示為0100 0001,然后將其右移2位,相對(duì)于取8位中的6位,與上面所說(shuō)一致。得到16,二進(jìn)制表示為0001 0000。之后我們補(bǔ)足了一個(gè)字節(jié)的6位還需要2位,后面的兩位需要由下一個(gè)字符貢獻(xiàn)4位,當(dāng)前字符貢獻(xiàn)2位。雖然我們輸入的A只有一個(gè)字符,但還是需要這樣算。我們?nèi)的末尾有效為兩位即與3(二進(jìn)制11)與運(yùn)算然后左移4位,之后用后面一個(gè)字符的右移4位組成一個(gè)新的字符,算出兩個(gè)值均為16,查表得16,因?yàn)锳用base64空了4位,需要用兩個(gè)==補(bǔ)足,因此A用base64表示得到了QQ==。
代碼實(shí)現(xiàn)
/*** 個(gè)人工具集合*/ window.Tool = (function(exports){'use strict';/*** base64處理工具*/class Base64{/*** 構(gòu)造函數(shù)*/constructor(){}/*** 編碼Base64* @param {string} input */static encode64(input){input = escape(input);//轉(zhuǎn)義字符var output = "";var c1,c2,c3 = "";var e1,e2,e3,e4 = "";var i = 0;do{c1 = input.charCodeAt(i++);//返回指定字符位置的Unicode編碼c2 = input.charCodeAt(i++);c3 = input.charCodeAt(i++);e1 = c1 >> 2;//右移2位 e2 = ((c1 & 3) << 4) | (c2 >> 4);//3二進(jìn)制:11e3 = c3 & 63;//63二進(jìn)制:111111if(isNaN(c2)){e3 = e4 = 64;//=}else if(isNaN(c3)){e4 = 64;//=}output = output + Base64.keyChar.charAt(e1) + Base64.keyChar.charAt(e2) + Base64.keyChar.charAt(e3) + Base64.keyChar.charAt(e4);c1 = c2 = c3 = "";e1 = e2 = e3 = e4 = ""; }while(i < input.length);return output;}/*** 解碼Base64* @param {string} input */static decode64(input){var output = "";var c1,c2,c3 = "";var e1,e2,e3,e4 = "";var i = 0;var base64test = /[^A-Za-z0-9\+\/\=]/g;if(base64test.exec(input)){alert("ERROR INPUT:base64字符只能包含A-Z,a-z,0-9,'+','/','='");return;}input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");do{e1 = Base64.keyChar.indexOf(input.charAt(i++));e2 = Base64.keyChar.indexOf(input.charAt(i++));e3 = Base64.keyChar.indexOf(input.charAt(i++));e4 = Base64.keyChar.indexOf(input.charAt(i++));c1 = (e1 << 2) | (e2 >> 4);//c2 = ((e2 & 15) << 4) | (e3 >> 2);//15二進(jìn)制:1111c3 = ((e3 & 3) << 6) | e4;//3二進(jìn)制:11output = output + String.fromCharCode(c1);if(e3 != 64){output = output + String.fromCharCode(c2);}if(e4 != 64){output = output + String.fromCharCode(c3);}c1 = c2 = c3 = "";e1 = e2 = e3 = e4 = "";}while(i < input.length);return unescape(output);}}Base64.keyChar = `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=`;exports.Base64 = Base64;return exports; }({}))?
總結(jié)
以上是生活随笔為你收集整理的理解Base64编码及实现编解码Base64的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Kubernetes v1.19 正式发
- 下一篇: 看完必会元编程