標籤:

如何用通俗易懂的語言解釋base64?


謝邀。

==============================

0 引言

這麼一道題其實本不應該邀請我嘛… 不過還是稍微懂一點點的,因為在密碼學實踐中,經常會用到Base64編碼。比如大名鼎鼎的密碼學挑戰題「Matasano Crypto Challenges」的第一集合的第一題,就是要求把一個Hex編碼的字元串轉化為Base64編碼的(Convert hex to base64),轉化前和轉化後的結果差不多是這個樣子:

轉化前:49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d

轉化後:SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t

那麼,Base64又是什麼呢?和我們聽說過的Hex編碼,ASCII編碼,UTF-8編碼什麼的,有什麼關係嗎?我盡量用簡單的語言來講講故事。

==============================

1 計算機開始之初,二進位與Hex

計算機這個東西,最初是美國人發明的。作為一個可以計算、存儲、通信的複雜玩意,最最基本的功能,應該是能讀懂人類讓它乾的事情。所以呢,我們得構造一個計算機能用的語言,這個語言計算機能看懂,人也能看懂,這樣才能交流嘛。

計算機所用的語言是什麼呢?這個語言非常簡單,只有0和1兩種表示。0代表否,1代表是。通過0和1的各種組合,以及0和1之間的各種運算(位運算),計算機就能進行理解、分析這個世界,並幫助人類完成工作了。

但是0和1太簡單了,簡單到任何一個簡單的數字都可能用一長串0和1來表示。舉了例子,如果讓計算機記住1000這個數,計算機就要記住11,1110,1000這麼長一串數字。計算機倒是好記,但是人類記不住啊… 有沒有一種方法,能夠讓計算機表示的數據短一點,好記一點呢?

Hex就是最簡單的方法了。人類習慣於使用十進位,畢竟人類有是個手指,十個一進位,挺好的!計算機本質上是二進位,就0和1兩種數字的表示方法,所有其他可以直接轉換的表示方法中,進位只能有2這個數,不能有其他的數字。比如4,8,16就沒問題。其他的數字,不管怎麼折騰,轉換後也得是2^n形式。

想讓人類和計算機都能接受表示形式,8進位和16進位都是可以接受的。8進位的話,只使用0-7折8個數字就好了。16進位,光用數字是不夠了,還得用用其他的字元。然而,計算機畢竟是美國人發明的,他們覺得,乾脆,就16進位:用0-9表示前10個數,後面的用A、B、C、D、E、F表示,不區分大小寫。這就是最簡單的Hex編碼了。

Hex的編碼原理是:把一長串二進位數每4個分一組,如果位數不夠就在高位補0。4位數字一共只有16種情況,分別用0-9,A-F表示這16種情況。編碼表類似這樣:

==============================

2 要讓可讀性更強:ASCII碼

Hex編碼雖然好,但有個問題:從計算機上打開個文件,滿眼的十六進位數,很頭大啊… 十六進位還是不太好表示文本。能不能創建一種方法,能表示鍵盤打出來的全部英文字元、符號呢?鍵盤打不出來的字元,比如什麼回車啦,佔位啦,用特殊的符號表示。這樣一來,打開一個文件,滿眼英文,豈不是很爽快…

美國作為計算機的始祖國家,自然要推出一個這樣的標準代碼表。這就是美國信息交換標準代碼,簡稱ASCII碼錶。這個碼錶包括了數字、英文大小寫、符號、以及各種各樣的轉義字元,可以包含英文所用的全部功能。很快地,ASCII碼稱為了國際標準,現在大家知道的編碼形式,都是與ASCII碼兼容的。(圖片來自:美國信息交換標準代碼)

==============================

3 別的語言怎麼辦?UTF-8等其他編碼方法

這個碼錶一出來,英語國家開心了…其他國家的腦袋疼了… 帶注音的符號怎麼辦?日語韓語怎麼辦?最為博大精深的中文怎麼辦… 於是,各個國家也推出了本國語言的編碼表。但是,為了能在計算機系統中通用,這些編碼表基本都與ASCII碼兼容。

最為知名的就是UTF-8了。這個編碼又稱為萬國碼,顧名思義,就是支持包括中文簡體、中文繁體、日語、韓語等各種語言的編碼。這玩意太複雜了… 我就不細說了。

==============================

4 用一種編碼形式打開另一種編碼形式 會怎樣?

既然每個國家都有自己的編碼表了,問題也就來了。現在都國際化了,我要用一個支持本國語言的編碼系統,打開另一個編碼系統編碼的文本,會出現什麼情況呢?這就是亂碼了… 更為嚴重的是,隨著互聯網的出現,各個國家的電腦都需要通信,而通信的一種方式就是使用URL地址。每個國家都希望把這個地址寫成自己國家的語言。但這會導致其他國家根本沒法訪問地址,因為打不出這個字元嘛。所以,人類迫切需要一種中間編碼形式,既能夠兼容ASCII碼,又能夠把任意一種編碼形式轉換成只使用可讀字元就能表示的編碼。其中一種編碼形式,就是Base64編碼。

Base64編碼,顧名思義,用64個可讀字元進行編碼。與Hex的16個字元相比多了很多,但是比ASCII碼又少了一倍,去除了不可讀字元。標準Base64編碼中,這些字元是:

  • 數字:0,1,2,3,4,5,6,7,8,9,共10個
  • 小寫字母:a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,共26個
  • 大寫字母:A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,共26個
  • 加好+以及斜杠/

有的時候,根據不同的需要,Base64還有很多變種。比如,如果瀏覽器地址中用「+」和「/」的話,瀏覽器會將其轉換為%XX的形式,又多了一步。因此可以將「+」和「/」換成「-」和「_」。

這種編碼形式長度也短,效率也高。這樣一來,數據通信的時候,不管來的是什麼語言,都轉化成Base64後再發送和接收。要是別國地址什麼的打不出來,就直接打Base64編碼形式就好了。如果細心的話,會發現百度雲盤共享的時候,用的就是Base64。舉個例子,前幾天有個朋友給我發送一個視頻,給的鏈接是這樣的(後面四位略去):

http://pan.baidu.com/s/1gdH****

前面都是標準的網頁形式,最後那個子文件,就是用Base64編碼的,而且可以在任何通信工具中傳遞,方便快捷啊。

==============================

5 誤區:Base64不是加密演算法

很多博客什麼的都把Base64當做加密演算法,這是不對的。Base64不具有可讀性,但不代表這個編碼是加密的。加密需要保證,沒有密鑰的人無法解密信息,無法從密文中獲得任何明文信息。Base64編碼顯然沒有密鑰什麼事… 所以,這個誤區大家要糾正過來。

以上。


將所有的0-127的ASCII碼 編程 a -z A -Z 0 -9 + / = 號組成的字元串 就這樣。。。在RSA安全演算法中,經常用來編碼key……也有在hmac和md5種編碼結果的,不符合習慣不過


讀完劉學酥的答案,說下我的理解。

所有的信息本質上都是二進位的0和1,所以各種眼花繚亂的編碼其實都是01組成的序列和字母符號漢字的對應關係。

比如 0100111100101010100011 這串二進位,在UTF-8里表示的是 「我是誰」。如果你想把「我是誰」轉化成BASE64,你就要先把「我是誰」轉化成「0100111100101010100011」 這串二進位,然後再把這串二進位轉化成 「ZG0abd12" 的BASE64 編碼。

(上面的UTF8和BASE64表示都是舉例)

如果不對,請指正。


我做過一個非常通俗易懂的課程(有簡潔的文字講解+動畫),看過的人都表示很通俗,你可以通過關注「jscourse」微信公眾號,然後回復「base64」獲取,由於發布在小程序上而且包含動畫效果,因此無法發布到知乎,你可以去看看,相信會對你理解 base64 編碼原理有所幫助


推薦閱讀:

早期的中國黑客大牛們現在都在幹什麼呢?
為什麼正版光碟無法完全複製?
加密手機真的需要加密晶元嗎?
TrueCrypt 为什么突然宣布不安全了?
破解密碼除了暴力破解還有什麼高端的方法?

TAG:加密 |