[C#] Base32 編碼/解碼方法 不分大小寫的編碼方式
前陣子在教學一篇 Base64 及 Base64Url 編碼 的方法,有提到可以將網址上傳送的資料採用 Base64 編碼。
但今天遇到一個特別的問題,因為網站上某些網址已經被搜尋引擎收錄,偶爾會有一些爬蟲程式到我的頁面上,而爬蟲程式使用的網址竟然全改為小寫,而我原本使用大小寫有別的 Base64 參數,造成解碼錯誤。
例如我原網址為: /Index/StraInfo/MTk0
參數 MTk0 可被 Base64 解碼
可是爬蟲程式呼叫網址為: /index/straInfo/mtk0
程式收到的參數為 mtk0 經過 Base64 解碼就無法正確還原了。
為了讓爬蟲程式使用全小寫網址可以正常瀏覽我的網站,我將原本 Base64 編碼的方式改為 Base32 編碼。
Base32 編碼為不分大小寫的編碼方式,編碼後可用的字母為
abcdefghijklmnopqrstuvwxyz234567
使用 Base32 編碼結果放在網址上當參數,也不會因為對方更改大小寫而造成解碼錯誤
Contents
Base32 編碼與解碼的方法
以下是我使用 Base32 編碼與解碼的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
/// <summary> /// Base 32 編碼 /// </summary> /// <param name="value"></param> /// <returns></returns> public string EncodeBase32(string value) { if (string.IsNullOrEmpty(value)) return null; string Alphabet = "abcdefghijklmnopqrstuvwxyz234567"; var valueBytes = Encoding.UTF8.GetBytes(value); var encodedBuilder = new StringBuilder(); var position = 0; var left = 0; for (var i = 0; i < valueBytes.Length * 8 / 5 + (valueBytes.Length * 8 % 5 == 0 ? 0 : 1); i++) { var encodedByte = default(byte); if (left > 0) { encodedByte |= (byte)(valueBytes[position] << (8 - left)); if (left <= 5 && position < valueBytes.Length - 1) { position++; if (left < 5) encodedByte |= (byte)(valueBytes[position] >> left); } } else { encodedByte |= valueBytes[position]; } encodedBuilder.Append(Alphabet[(byte)(encodedByte >> 3)]); left = 8 * (position + 1) - 5 * (i + 1); } return encodedBuilder.ToString(); } /// <summary> /// Base 32 解碼 /// </summary> /// <param name="value"></param> /// <returns></returns> public string DecodeBase32(string value) { if (string.IsNullOrEmpty(value)) return null; string Alphabet = "abcdefghijklmnopqrstuvwxyz234567"; value = value.ToLower().TrimEnd('='); var decodedBytes = new byte[value.Length * 5 / 8]; var position = 0; var available = 0; for (var i = 0; i < value.Length; i++) { var symbol = (byte)(Alphabet.IndexOf(value[i]) << 3); if (available > 0) { decodedBytes[position] |= (byte)(symbol >> (8 - available)); if (available <= 5 && position < decodedBytes.Length - 1) { decodedBytes[++position] |= (byte)(symbol << available); } } else { decodedBytes[position] |= symbol; } available = 8 * (position + 1) - 5 * (i + 1); } return Encoding.UTF8.GetString(decodedBytes); } |
程式碼中的語法
string Alphabet = "abcdefghijklmnopqrstuvwxyz234567";
可以修改為
string Alphabet = " ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
這樣編碼結果字母就可以為全大寫。
Base32 優缺點比較
使用 Base32 當網址參數有幾個好處
1. 適用不分大小寫的環境
2. 數字少了 0, 1 ,避免與 O, I 混淆
3. 當網址參數不需要用 HttpUtility.UrlEncode()
再編碼
而缺點的話包含
1. 編碼後長度膨脹約 60%,比 Base64 膨脹 33% 還多。
2. 在 .Net 沒有內建支援的方法,需要自己寫。
3. 並非為常見編碼方式
有關 Base32 的編碼說明可以參考維基百科
相關學習文章
如果你在學習上有不懂的地方,需要諮詢服務,可以參考站長服務,我想辨法解決你的問題
如果文章內容有過時、不適用或錯誤的地方,幫我在下方留言通知我一下,謝謝