前阵子在教学一篇 Base64 及 Base64Url 编码 的方法,有提到可以将网址上传送的资料采用 Base64 编码。
但今天遇到一个特别的问题,因为网站上某些网址已经被搜寻引擎收录,偶尔会有一些爬虫程序到我的页面上,而爬虫程序使用的网址竟然全改为小写,而我原本使用大小写有别的 Base64 参数,造成解码错误。
例如我原网址为: /Index/StraInfo/MTk0
参数 MTk0 可被 Base64 解码
可是爬虫程序呼叫网址为: /index/straInfo/mtk0
程序收到的参数为 mtk0 经过 Base64 解码就无法正确还原了。
为了让爬虫程序使用全小写网址可以正常浏览我的网站,我将原本 Base64 编码的方式改为 Base32 编码。
Base32 编码为不分大小写的编码方式,编码後可用的字母为
abcdefghijklmnopqrstuvwxyz234567
使用 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 的编码说明可以参考维基百科
[C#] Convert.ToBase64String 基本转码及适用网址参数转码延伸应用
>>: TP-LINK ARCHER C60及TL-WR841N有线接WAN的AP模式和有线桥接差在那?
题库一个人不容易维护 如果想要多人共用试算表 就会怕有些人动到你设定好的格式 此时可以选择保护工作表...
这系列的文章不会讲完全部 KSP 的实作,毕竟我也还正在实作中,不过实作的方向应该是跟前几篇讲的差不...
我自己秉持着最少力气解决问题,但换句话说就是,有点得过且过,尤其如果快要放假的时候,这时候“选对环境...
前言 昨天已经在storyboard上将tableView连结上程序中的table,不过并没有解释到...
你听过的有AI框架有scikit-learn(机器学习)、tensorflow(深度学习)、pyto...