1. 程式人生 > >base64編碼以及url safe base64是怎麼工作的?

base64編碼以及url safe base64是怎麼工作的?

原文轉自 http://www.yanshiba.com/archives/638

1: 為什麼需要base64?

ASCII碼一共規定了128個字元的編碼,這128個符號,範圍在[0,127]之間.
其中,[0,31],及127, 33個屬於不可列印的控制字元.

在電子郵件傳輸資訊時,有些郵件閘道器會把[0,31]這些控制字元給悄悄清除.
還有的早期程式,收到[128,255]之間的國際字元時,甚至會發生錯誤.

如何在不同郵件閘道器之間安全的傳輸控制字元,國際字元,甚至二進位制檔案?
於是作為MIME多媒體電子郵件標準的一部分—base64被開發出來.

1.a 什麼是url_safe base64編碼?

在上面的base64傳統編碼中會出現+, /兩個會被url直接轉義的符號,因此如果希望通過url傳輸這些編碼字串,我們

需要先做傳統base64編碼,隨後將+和/分別替換為- _兩個字元,在接收端則做相反的動作解碼

http://www.ietf.org/rfc/rfc4648.txt

  /**
     * URL base64解碼
     * '-' -> '+'
     * '_' -> '/'
     * 字串長度%4的餘數,補'='
     * @param unknown $string
     */
  function urlsafe_b64decode($string) {
        $data = str_replace(array('-','_'),array('+','/'),$string
); $mod4 = strlen($data) % 4; if ($mod4) { $data .= substr('====', $mod4); } return base64_decode($data); } /** * URL base64編碼 * '+' -> '-' * '/' -> '_' * '=' -> '' * @param unknown $string */ function urlsafe_b64encode($string
) { $data = base64_encode($string); $data = str_replace(array('+','/','='),array('-','_',''),$data); return $data; }

2: 一句話說完base64怎麼工作的?

把N位元組的內容對應的8*N位, 每6位砍成1段,得到 (8*N)/6 個單元,
每個單元的值,都在[0,63]之間,再把其值對應1個ascii字元,拼接起來,OK!

base64_encode(’PHP’) ==> ‘UEhQ’, 編碼過程如下:

3: 如果每6位砍成1段,但不能整除,餘下2個位或4位怎麼辦?

用”0″來補至6位, 並再次轉化為”base64字元表”中的某個字元.

然後,再用”=”字元當做6個位,繼續填充,直至總位數能被8帶整除.

字串 二進位制序列(紅字為填充位) 編碼結果
PHP 010100 000100 100001 010000 UEhQ
it 011010 010111 0100

00 xxxxxx

aXQ=
bool 011000 100110 111101 101111 011011 00

0000 xxxxxx xxxxxx

Ym9vbA==

4:base64表示圖片

通過上面的演示,可以看出,base64也可以編碼二進位制檔案,如郵件中的圖片和附件.
編碼後,我們可以在網頁或郵件的原始碼裡,直接體現此圖片,
而不必把圖片放在伺服器上,引用其連結.

用例:base64(’abc.png’) ==> ‘encoded-result’;
則在網頁中, <img src=”data:image/png;base64,encoded-result” />

看到下面這個5角星了嗎? 右鍵看原始碼,就會發現圖片是一串字串 :)

5: base64編碼後位元組的變化

很容易推算出, 編碼後,每6個位變成8個位.
因此,編碼後位元組約比編碼前多33%.

6: base64串結尾的”=”可以去掉嗎?

從上面的編碼規則可以反推出, 在base64解碼的過程中, 要清除掉結尾處的等號,
然後再反查”base64索引與字母對照表”,轉換成原始的位元組序列.

那麼,去掉尾部的等號,並沒有丟失原始資訊,但結構變得不規範.
解碼前是否判斷完整性,這取決於你的應用程式.

實測PHP中的base64_decode函式,並不檢測尾部的等號是否完整.