Base32編碼是使用32個可打印字符(字母A-Z和數字2-7)對任意字節數據進行編碼的方案,編碼後的字符串不用區分大小寫並排除了容易混淆的字符,能夠方便地由人類使用並由計算機處理。 Base32主要用於編碼二進制數據,可是Base32也可以編碼諸如ASCII之類的二進制文本。
Base32將任意字符串按照字節進行切分,並將每一個字節對應的二進制值(不足8比特高位補0)串聯起來,按照5比特一組進行切分,並將每組二進制值轉換成十進制來對應32個可打印字符中的一個。
因爲數據的二進制傳輸是按照8比特一組進行(即一個字節),所以Base32按5比特切分的二進制數據必須是40比特的倍數(5和8的最小公倍數)。例如輸入單字節字符「%」,它對應的二進制值是「100101」,前面補兩個0變成「00100101」(二進制值不足8比特的都要在高位加0直到8比特),從左側開始按照5比特切分紅兩組:「00100」和「101」,後一組不足5比特,則在末尾填充0直到5比特,變成「00100」和「10100」,這兩組二進制數分別轉換成十進制數,經過上述表格便可找到其對應的可打印字符「E」和「U」,可是這裏只用到兩組共10比特,還差30比特達到40比特,按照5比特一組還需6組,則在末尾填充6個「=」。填充「=」符號的做用是方便一些程序的標準化運行,大多數狀況下不添加也可有可無,並且,在URL中使用時必須去掉「=」符號。
它可用來做爲電子郵件的傳輸編碼。在Base64中的可打印字符包括字母A-Z、a-z、數字0-9,這樣共有62個字符,此外兩個可打印符號在不一樣的系統中而不一樣。一些如uuencode的其餘編碼方法,和以後BinHex的版本使用不一樣的64字符集來表明6個二進制數字,可是不被稱爲Base64。
base85 也稱爲Ascii85,是Paul E. Rutter爲btoa實用程序開發的一種二進制文本編碼形式。經過使用五個ASCII字符來表示四個字節的二進制數據(使編碼量1 / 4比原來大,假設每ASCII字符8個比特),它比更有效UUENCODE或Base64的,它使用四個字符來表示三個字節的數據(1 / 3的增長,假設每ASCII字符8個比特)。
它的主要現代用途是Adobe的PostScript和Portable Document Format文件格式,以及Git使用的二進制文件的補丁編碼。
與Base64同樣,Base85編碼的目標是對二進制數據可打印的ASCII字符進行編碼。可是它使用了更大的字符集,所以效率更高一些。具體來講,它能夠用5個字符編碼4個字節(32位)。
摘自wiki介紹的一個例子:
Base36
Base36是一個二進制到文本編碼表示方案的二進制數據以ASCII經過將其轉化爲一個字符串格式基數 -36表示。選擇36十分方便,由於可使用阿拉伯數字 0–9和拉丁字母 A–Z [1](ISO基本拉丁字母)表示數字。
每一個base36位須要少於6位的信息來表示。
摘自wiki的一個例子:
有符號的32位和64位整數分別最多隻能容納6個或13個base-36位數字(許多base-36位數字可能會使32位和64位整數溢出)。
例如,在base-36中,「 922337203685477575807 」 的64位帶符號整數最大值爲「 1Y2P0IJ32E8E7 」。
相似地,在base-36中,「 2147483647 」 的32位帶符號整數最大值爲「 ZIK0ZJ 」。
(這裏沒看太懂是怎麼轉換的,請大佬指教~)
用於從BASE10編碼BASE36的Python代碼
def base36encode(integer):
chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
sign = '-' if integer < 0 else ''
integer = abs(integer)
result = ''
while integer > 0:
integer, remainder = divmod(integer, 36)
result = chars[remainder]+result
return sign+result
Base58
Base58是用於Bitcoin中使用的一種獨特的編碼方式,主要用於產生Bitcoin的錢包地址。相比Base64,
Base58不使用數字"0",字母大寫"O",字母大寫"I",和字母小寫"l",以及"+"和"/"符號。
設計Base58主要的目的是:
-
避免混淆。在某些字體下,數字0和字母大寫O,以及字母大寫I和字母小寫l會很是類似。
-
不使用"+"和"/"的緣由是非字母或數字的字符串做爲賬號較難被接受。
-
沒有標點符號,一般不會被從中間分行。
-
大部分的軟件支持雙擊選擇整個字符串。
Base91
basE91是將二進制數據編碼爲ASCII字符的高級方法。
它相似於UUencode或base64,但效率更高。 basE91產生的開銷取決於輸入數據。
它的數量最多爲23%(而base64爲33%),範圍能夠下降到14%,一般發生在0字節塊上。
這使得basE91對於經過二進制不安全鏈接(例如電子郵件或終端線)傳輸較大的文件很是有用。
顧名思義,basE91須要91個字符來表示ASCII編碼的二進制數據。 從94個可打印ASCII字符(0x21-0x7E)中,如下三個字符被省略以構建basE91字母:
-(破折號,0x2D)
\(反斜槓,0x5C)
'(撇號,0x27)
轉換表由其他字符組成,以下所示。
Base92
有關Base92的資料實在是不多,可是筆者找到了這一篇博客:
https://thenoviceoof.com/blog/projects/base92/
如下介紹均摘自這篇博客
「 若是您對將二進制信息從一個地方轉移到另外一地方一無所知,那麼就知道將數據從一個地方轉移到另外一地方 可能很危險。就是說,這對您的數據有害:也許您須要在僅用於ASCII文本的通道上傳輸Blob ,而且全部'\n'以C樣式字符串表示的字節都會忽然有一個同級符號'\r'。或者,您的傳輸層實際上真的真的是以null終止的字符串,而且您剛好在字節邊界上連續有8個連續的0位,即便它位於blob中一個32位整數的中間,而且你結束了只有一半您的數據。
解決此問題的一種方法是使用base64,它使用全部數字和大寫/小寫字母字符對數據進行編碼(再加上兩個,但如今咱們將忽略它們)。如今,您在傳輸層上嘗試解釋您的字節時沒有任何問題,由於每一個人均可以很好地處理字母數字字符,若是沒有,您可能不想使用它們。
固然,使用base64了一段時間後,您可能會注意到,雖然您不會由於一位反覆無常的上帝覺得他在提供幫助,卻沒有按照本身的意願對數據進行更改,但您卻經過使用放棄了效率base64。對於二進制blob中的每3個字節,若是須要傳輸字母數字字符,則有4個字節,所以您要以33%的容量稅來支付數據保護費用:若是暴徒能夠在保護球拍中掠走33%,相信他們會的。
看一下base64,您可能會注意到,除了可使用的64個字符外,還有更多可顯示的ASCII字符,base64能夠在編碼中使用這些字符以提升傳輸密度。這樣就base85誕生了,使用了……您猜對了,有85個字符!此次,將4字節的二進制數據編碼爲5個ASCII字符,這將致使20%的傳輸大小開銷。但你能作什麼呢?好像沒有更多可顯示的ASCII了……哦,等等。
因此彷佛沒有人試圖超越明顯的下一步base85,因此我決定嘗試本身作base92。
在鍵入編碼的字符串時,`和「與普通引號'太類似,以使其溫馨。但願在區分l / 1和0 / O時使用的字體好。
可是,咱們將〜用做特殊符號(空字符串)。有94個可打印的ascii字符,所以咱們最終獲得91個字符,或每一個字符6.5位。一旦包含〜,則將有92個字符:所以,爲base92。
(老實說,base91的名字太醜陋了,沒法處理)
一旦每一個字符有6.5位,則能夠一次使用13位,並使用相似於base85的除法和取模方案,用它們產生兩個輸出字符。這可能意味着,與base92編碼相比,它更能抵抗損壞,由於任何損壞都更加侷限(一位更改僅影響2-3個字節,而不影響4個字節)。
注意:在某些須要某些輸出的狀況下,可能須要將〜用做空字符串分號:可是,傳遞空字符串進行解碼不會致使它變成barf,所以不要求使用〜。
旁註:之前base92產生的輸出的長度與輸入的長度非單調增加。這已再也不是這種狀況。
另外一個旁註:base64和base85更加優雅,將一個較小的字節整數乾淨地映射到另外一個較小的字節整數。base92將13個字節映射爲16個字符,從大小的角度來看,這比base85的4至5個字符更好,可是至關不雅觀。
咱們還遵循使用高除數乘積做爲第一個字節的base85約定。」
Base62
Base62編碼將數字轉換爲ASCII字符串(0-9,az和AZ),反之亦然,這一般會致使字符串較短。
26個小寫字母+26個大寫字母+10個數字=62
(1)62進制與10進制的互相轉化
62進制轉10進制與2進制轉10進制類似。
2進制轉10進制過程爲: 從右到左用二進制的每一個數去乘以2的相應次方,次方要從0開始。
62進制轉10進制也相似,從右往左每一個數*62的N次方,N從0開始。
那麼,10進制轉62進制也與10進制轉2進制相似。
即:不斷除以62取餘數,而後倒序。
(2)關於短Url的轉換
主要思路,維護一個全局自增的id,每來一個長url,將其與一個自增id綁定,而後利用base62將該自增id轉換爲base62字符串,即完成轉換。
以上就是對Base系列編碼的淺析,部分知識是筆者從wiki上搬運過來的,也參考了不少博客文章和資料。若有錯誤及不足之處,請大佬們多提建議~
參考資料:
https://en.wikipedia.org/wiki
https://blog.csdn.net/n0nameforn0w/article/details/87124053
https://thenoviceoof.com/blog/projects/base92/
https://segmentfault.com/a/1190000010516708