[C#] Base32 编码/解码方法 不分大小写的编码方式

前阵子在教学一篇 Base64 及 Base64Url 编码 的方法,有提到可以将网址上传送的资料採用 Base64 编码。

但今天遇到一个特别的问题,因为网站上某些网址已经被搜寻引擎收录,偶尔会有一些爬虫程式到我的页面上,而爬虫程式使用的网址竟然全改为小写,而我原本使用大小写有别的 Base64 参数,造成解码错误。

例如我原网址为: /Index/StraInfo/MTk0
参数 MTk0 可被 Base64 解码

可是爬虫程式呼叫网址为: /index/straInfo/mtk0
程式收到的参数为 mtk0 经过 Base64 解码就无法正确还原了。

为了让爬虫程式使用全小写网址可以正常浏览我的网站,我将原本 Base64 编码的方式改为 Base32 编码。
Base32 编码为不分大小写的编码方式,编码后可用的字母为
abcdefghijklmnopqrstuvwxyz234567

使用 Base32 编码结果放在网址上当参数,也不会因为对方更改大小写而造成解码错误

Base32 编码与解码的方法

以下是我使用 Base32 编码与解码的方法

/// <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 当网址参数有几个好处

适用不分大小写的环境数字少了 0, 1 ,避免与 O, I 混淆当网址参数不需要用 HttpUtility.UrlEncode() 再编码

而缺点的话包含

编码后长度膨胀约 60%,比 Base64 膨胀 33% 还多。在 .Net 没有内建支援的方法,需要自己写。并非为常见编码方式

有关 Base32 的编码说明可以参考维基百科

相关学习文章

[C#] Convert.ToBase64String 基本转码及适用网址参数转码延伸应用


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章