
在 在編碼方式如 Base64、Base32 中,所謂的填充(padding)是什麼意思? 一文中,筆者說明並舉例了在編碼方式中所謂的填充(padding)是什麼意思;那麼究竟什麼時候需要考慮到編碼方式是否因填充字元帶來影響呢?
編碼使用場景
一個十分常見的場景是當 編碼後的字串需要作為 URL 中的一部分 時,在 RFC 3986 規範中定義了統一資源標識符(Uniform Resource Identifier, URI)的通用格式,以確保兼容性與安全性:
- 字元
:
、/
、?
、#
、[
、]
、@
、!
、&
、'
、(
、)
、*
、+
、,
、;
、=
作為保留字元(reserved characters),具有特殊用途,不得隨意使用,否則會影響解析。 - 字元
A-Z
、a-z
、0-9
、-
、.
、_
和~
為非保留字元,可以安全出現在 URI 中,不需要額外編碼。 - 對於中文、空白等特殊字元,需要轉換為百分號編碼(Percent-Encoding)。
因此 Base64 編碼並不能用做 URL 而需要採 URL-Safe Base64 編碼才行。
+
替換為 -
、/
替換為 _
並看需求決定是否要移除填充字元 =
。
適合短網址的編碼方式
在系統設計(system design)面試中,短網址服務幾乎可以說是常客中的常客了,但在這裡我們暫且不討論系統負載、資料庫選擇以及 API 設計,僅僅承接前面的話題:編碼(Encoding)。
你有想過怎麼樣的編碼適合用於短網址服務嗎?選擇適當的編碼方式,會影響到編碼後的 辨識性、安全性 與 壓縮率:
- Base58 移除了易混淆字元,提高了辨識性,並且不存在特殊字元或 URI 保留字元,不需要額外轉換,不保證唯一性。
- Base62 保留使用數字和大小寫字母,但避免
+
和/
等字元,相較 Base64 來說更短,不保證唯一性。 - URL-Safe Base64 是 Base64 編碼的變體,將其中的保留字元與填充字元替換以避免違反 URI 的格式規範,不保證唯一性。
- SHA-256 雜湊 透過雜湊函數將長字串壓縮為固定長度,保證了唯一性。
其中適合短網址的編碼方式,主要為 Base58 編碼與 Base62 編碼,而 URL-Safe Base64 一般更常見於 API Token 或 JWT 中;當涉及需要具備唯一性的短網址或識別碼時,則會採用 SHA-256 雜湊。
唯一性不夠,拿 UUID 來湊
唯一性指的是每個編碼的結果都是獨一無二的,不會與其他值發生衝突,這在短網址服務、識別碼、加密貨幣地址等應用中特別重要。
在程式開發中,我們經常會使用具備高度唯一性的 UUID 或 GUID 來作為標識方式,或者資料庫中資料的主鍵(primary key),又或者是增量的 ID 來確保唯一性;前面提及 Base58、Base62 和 URL-Safe Base64 編碼並不能保證唯一性,而 SHA-256 雖然具備唯一性,但編碼後長度又顯得太長,那麼有什麼辦法呢?
答案想必你也知道了:「唯一性不夠,拿 UUID 來湊」,我們可以 使用 UUID 作為資料的主鍵(primary key),再使用 Base58 編碼將其轉換為辨識性高、長度不會太長,且理論上不會產生相同結果的字串。
當然啦!實際上在設計短網址服務時,採用增量 ID 搭配 Base58 編碼就能夠確保唯一性,並且生成的識別碼長度也較短;又或者是使用雜湊表與一組短碼進行映射,但這就不是本文想要探討的範圍了。
張貼留言