urlencode :将目标字符串按照特定的编码(比如utf-8、gb2312) 解码成byte数组,
然后对除这些字符集(a-z,A-Z,\,(,),*,-,.,_,!) 之外的所有字节(8位)转换成%加16进制字符,其中空格特殊处理将转换成+号。
比如?号,十进制为63,二进制为11 1111 ,经过urlencode后变为%3f
具体算法如下:(reflector编译的)
/// <summary>
/// 10进制转16进制( 10->a ,11->b
/// </summary>
/// <param name="n"></param>
/// <returns></returns>
internal static char IntToHex(int n)
{
if (n <= 9)
{
return (char)(n + 0x30);
}
return (char)((n - 10) + 0x61);
}
private static int HexToInt(char h)
{
if ((h >= '0') && (h <= '9'))
{
return (h - '0');
}
if ((h >= 'a') && (h <= 'f'))
{
return ((h - 'a') + 10);
}
if ((h >= 'A') && (h <= 'F'))
{
return ((h - 'A') + 10);
}
return -1;
}
private static byte[] UrlDecodeBytesFromBytesInternal(byte[] buf, int offset, int count)
{
int length = 0;
byte[] sourceArray = new byte[count];
for (int i = 0; i < count; i++)
{
int index = offset + i;
byte num4 = buf[index];
if (num4 == 0x2b)//+
{
num4 = 0x20;//空格
}
else if ((num4 == 0x25) && (i < (count - 2)))//0x25=%
{
int num5 = HexToInt((char)buf[index + 1]);//高4位
int num6 = HexToInt((char)buf[index + 2]);//低4位
if ((num5 >= 0) && (num6 >= 0))
{
num4 = (byte)((num5 << 4) | num6);
i += 2;
}
}
sourceArray[length++] = num4;
}
if (length < sourceArray.Length)
{
byte[] destinationArray = new byte[length];
Array.Copy(sourceArray, destinationArray, length);
sourceArray = destinationArray;
}
return sourceArray;
}
private static byte[] UrlEncodeBytesToBytesInternal(byte[] bytes, int offset, int count, bool alwaysCreateReturnValue)
{
int num = 0;
int num2 = 0;
for (int i = 0; i < count; i++)
{
char ch = (char)bytes[offset + i];
if (ch == ' ')
{
num++;
}
else if (!IsSafe(ch))
{
num2++;
}
}
if ((!alwaysCreateReturnValue && (num == 0)) && (num2 == 0))
{
return bytes;
}
byte[] buffer = new byte[count + (num2 * 2)];
int num4 = 0;
for (int j = 0; j < count; j++)
{
byte num6 = bytes[offset + j];
char ch2 = (char)num6;
if (IsSafe(ch2))
{
buffer[num4++] = num6;
}
else if (ch2 == ' ')
{
buffer[num4++] = 0x2b;//+
}
else
{
buffer[num4++] = 0x25;//%
buffer[num4++] = (byte)IntToHex((num6 >> 4) & 15);//高4位
buffer[num4++] = (byte)IntToHex(num6 & 15);//1111 与15与 取低4位
}
}
return buffer;
}