Base64簡介

最近開發過程當中常常會須要Base64編碼,MD5,加密等功能,這些頻繁使用的小工具要常常到網上找,並且還都不太好用,就本身開發了一個, codoolo。在實現Base64的過程,也學到了不少。這篇文件記錄Base64相關的知識,歡迎指正。

Base64是什麼?

Base64早已經被普遍使用了,尤爲是Multipurpose Internet Mail Extensions (MIME)。html

wikipedia中對Base64的定義:安全

Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation.

簡單來講,Base64使用了指定的64個字符對數據編碼,而這64個字符中不包括特殊字符(以避免被一些應用認爲是控制字符,若是ftp,ssh等),這樣通過編碼的數據能夠在網絡中安全的傳輸。網絡

如何實現Base64?

首先須要挑選64個字符。RFC 4648定義了Base64的字符集:ssh

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/工具

下圖顯示如何將字符串「xyz」編碼爲「eH16」的過程編碼

steps to encode 3 chars

步驟:

  1. 把每一個字符轉換爲整數,也就是字符在ASCII中的位置
  2. 將整數轉換爲二進制表示
  3. 每六位一組,轉爲整數,並在上面的Base64字符集中找到該整數所在位置的字符
  4. 將獲得的字符鏈接起來,獲得最終的結果

第二步和第三步實際上是一系列位操做,並不須要真的轉換,這裏爲了將編碼過程闡述清楚,加了這兩個步驟。加密

因爲6位正好能夠表示64,因此每3個8位的字符(24bit)能夠編碼爲4個Base64字符(4個6bit=24bit)。但編碼後的每一個字符的存儲仍然須要8位。這意味着Base64編碼後的存儲空間增長了1/3spa

由此認識到:

Base64使用6 bits重組數據,但重組後的每一個字符仍然須要8 bit的存儲空間。因此Base64是用較小的字符集表示數據,但存儲空間卻所以增長了,所謂有一利必有一弊。code

URL和文件名

在上面的Base64字符集中包括了 '+/' ,而通常的URL和文件名中,不能使用這兩個字符,因此RFC4686提議使用另一個字符集:orm

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_

而具體用哪一個字符集,要考慮使用的場景。好比只是在項目內部使用,編解碼均可控,那麼就可使用第二個,甚至可使用一個自定義的字符集。但若是是將數據給第三方,那麼使用第一個字符集更好,由於大部分庫的實現都使用了第一個字符集。

若是數據的長度不是3的倍數怎麼辦?

咱們剛剛說了如何將3個字符應用Base64編碼,但若是字符串的長度不是3的倍數怎麼辦?

若是最後還有兩個字符須要編碼:
steps to encode 2 chars

好比"xy",2個字符有16 bits,那麼前12 bits能夠編碼爲"eH",對於剩下的4 bits,在右側填充2個0,因此第三個字符是"k"。有時,網絡中傳輸的數據長度是未知的,這時爲了肯定知道數據是否截止,則須要將編碼的數據補齊爲4的倍數。對於Base64編碼,使用 = 來補齊,也就是第65個字符

若是最後只有一個字符,過程相似:

steps to encode 1 char

須要注意的是,最後使用了2個 == 來補齊。

請問,若是一個Base64編碼的最後有3個=,即===,這是一個合法的Base64編碼麼?

若是數據不是ASCII碼呢?

咱們上面討論編碼的時候,都假設輸入的是ASCII,即字符是0x00-0xFF之間的。那若是輸入的字符是UTF-8呢?好比:

「こんにちは」 或者 「你好」

通常有兩種方式來處理:

  • 在編碼前轉義字符串
  • 將UTF-8轉爲bytes

因此在實現codoolo時, 若是輸入的是非ASCII碼,會提示選擇一個轉換器:

show converter for non ASCII

如何解碼?

瞭解了編碼過程,相信解碼就比較簡單了,也就是將上面的過程逆向執行就能夠。

還有什麼?

說實話,我一直在使用Base64編碼,到從沒想過一個Base64編碼也要有這麼多須要注意的地方,並且還有問題:

  • 當將漢字等編碼後,在解碼時若是直接輸出漢字?
  • Base64使用了更多的存儲空間,那麼是否是可使用Base128呢?
  • 若是我使用一個特殊的字符集,這樣編碼出來的數據有多安全?容易破解麼?
  • 如何提升編解碼的效率?

咱們之後接着聊。

相關文章
相關標籤/搜索