------ #### MyDbV4 V3.0.2107.2901 - *.[新增]新增支持计算文件MD5。 - *.[新增]部分DataProvider功能移植到DbExtension里,增加扩展性。 - *.[新增]UnixTimeToDateTime和JSTimeToDateTime新增支持long参数。 - *.[合并]合并RyWeb项目到MyDb里。 #### ryControlsV4 V3.0.2107.2901 - *.[改进]优化减少大量IDE警告和消息。
468 lines
15 KiB
C#
468 lines
15 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
|
|
namespace RyWeb
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public class UrlDecoder
|
|
{
|
|
// Fields
|
|
private readonly int _bufferSize;
|
|
private byte[] _byteBuffer;
|
|
private readonly char[] _charBuffer;
|
|
private readonly Encoding _encoding;
|
|
private int _numBytes;
|
|
private int _numChars;
|
|
internal UrlDecoder(int bufferSize, Encoding encoding)
|
|
{
|
|
this._bufferSize = bufferSize;
|
|
this._encoding = encoding;
|
|
this._charBuffer = new char[bufferSize];
|
|
}
|
|
internal void AddByte(byte b)
|
|
{
|
|
if (this._byteBuffer == null)
|
|
{
|
|
this._byteBuffer = new byte[this._bufferSize];
|
|
}
|
|
this._byteBuffer[this._numBytes++] = b;
|
|
}
|
|
internal void AddChar(char ch)
|
|
{
|
|
if (this._numBytes > 0)
|
|
{
|
|
this.FlushBytes();
|
|
}
|
|
this._charBuffer[this._numChars++] = ch;
|
|
}
|
|
internal string GetString()
|
|
{
|
|
if (this._numBytes > 0)
|
|
{
|
|
this.FlushBytes();
|
|
}
|
|
if (this._numChars > 0)
|
|
{
|
|
return new string(this._charBuffer, 0, this._numChars);
|
|
}
|
|
return string.Empty;
|
|
}
|
|
private void FlushBytes()
|
|
{
|
|
if (this._numBytes > 0)
|
|
{
|
|
this._numChars += this._encoding.GetChars(this._byteBuffer, 0, this._numBytes, this._charBuffer, this._numChars);
|
|
this._numBytes = 0;
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public class WebDecode
|
|
{
|
|
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 string UrlDecodeStringFromStringInternal(string s, Encoding e)
|
|
{
|
|
int length = s.Length;
|
|
UrlDecoder decoder = new UrlDecoder(length, e);
|
|
for (int i = 0; i < length; i++)
|
|
{
|
|
char ch = s[i];
|
|
if (ch == '+')
|
|
{
|
|
ch = ' ';
|
|
}
|
|
else if ((ch == '%') && (i < (length - 2)))
|
|
{
|
|
if ((s[i + 1] == 'u') && (i < (length - 5)))
|
|
{
|
|
int num3 = HexToInt(s[i + 2]);
|
|
int num4 = HexToInt(s[i + 3]);
|
|
int num5 = HexToInt(s[i + 4]);
|
|
int num6 = HexToInt(s[i + 5]);
|
|
if (((num3 < 0) || (num4 < 0)) || ((num5 < 0) || (num6 < 0)))
|
|
{
|
|
goto Label_0106;
|
|
}
|
|
ch = (char)((((num3 << 12) | (num4 << 8)) | (num5 << 4)) | num6);
|
|
i += 5;
|
|
decoder.AddChar(ch);
|
|
continue;
|
|
}
|
|
int num7 = HexToInt(s[i + 1]);
|
|
int num8 = HexToInt(s[i + 2]);
|
|
if ((num7 >= 0) && (num8 >= 0))
|
|
{
|
|
byte b = (byte)((num7 << 4) | num8);
|
|
i += 2;
|
|
decoder.AddByte(b);
|
|
continue;
|
|
}
|
|
}
|
|
Label_0106:
|
|
if ((ch & 0xff80) == 0)
|
|
{
|
|
decoder.AddByte((byte)ch);
|
|
}
|
|
else
|
|
{
|
|
decoder.AddChar(ch);
|
|
}
|
|
}
|
|
return decoder.GetString();
|
|
}
|
|
/// <summary>
|
|
/// url解密
|
|
/// </summary>
|
|
/// <param name="str"></param>
|
|
/// <param name="e"></param>
|
|
/// <returns></returns>
|
|
public static string UrlDecode(string str, Encoding e)
|
|
{
|
|
if (str == null)
|
|
{
|
|
return null;
|
|
}
|
|
return UrlDecodeStringFromStringInternal(str, e);
|
|
}
|
|
/// <summary>
|
|
/// url解密,按UTF8方式解密
|
|
/// </summary>
|
|
/// <param name="s"></param>
|
|
/// <returns></returns>
|
|
public static string UrlDecode(string s)
|
|
{
|
|
Encoding e = Encoding.UTF8;
|
|
return UrlDecode(s, e);
|
|
}
|
|
/// <summary>
|
|
/// Url加密
|
|
/// </summary>
|
|
/// <param name="str"></param>
|
|
/// <param name="encode"></param>
|
|
/// <returns></returns>
|
|
public static string UrlEncode(string str, Encoding encode)
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
byte[] byStr = encode.GetBytes(str); //默认是System.Text.Encoding.Default.GetBytes(str)
|
|
for (int i = 0; i < byStr.Length; i++)
|
|
{
|
|
sb.Append(@"%" + Convert.ToString(byStr[i], 16));
|
|
}
|
|
return (sb.ToString().Replace(" ", "+"));
|
|
}
|
|
/// <summary>
|
|
/// Url加密,按UTF8方式加密
|
|
/// </summary>
|
|
/// <param name="str"></param>
|
|
/// <returns></returns>
|
|
public static string UrlEncode(string str)
|
|
{
|
|
return UrlEncodeNonAscii(str,Encoding.UTF8).Replace(" ", "+");
|
|
}
|
|
private static int HexDigit(char c)
|
|
{
|
|
if ((c >= '0') && (c <= '9'))
|
|
{
|
|
return (c - '0');
|
|
}
|
|
if ((c >= 'A') && (c <= 'F'))
|
|
{
|
|
return (('\n' + c) - 0x41);
|
|
}
|
|
if ((c >= 'a') && (c <= 'f'))
|
|
{
|
|
return (('\n' + c) - 0x61);
|
|
}
|
|
return -1;
|
|
}
|
|
/// <summary>
|
|
/// 解密
|
|
/// </summary>
|
|
/// <param name="string"></param>
|
|
/// <returns></returns>
|
|
public static string Unescape(object @string)
|
|
{
|
|
string str = Convert.ToString(@string);
|
|
int length = str.Length;
|
|
StringBuilder builder = new StringBuilder(length);
|
|
int num6 = -1;
|
|
while (++num6 < length)
|
|
{
|
|
char ch = str[num6];
|
|
if (ch == '%')
|
|
{
|
|
int num2;
|
|
int num3;
|
|
int num4;
|
|
int num5;
|
|
if (((((num6 + 5) < length) && (str[num6 + 1] == 'u')) && (((num2 = HexDigit(str[num6 + 2])) != -1) && ((num3 = HexDigit(str[num6 + 3])) != -1))) && (((num4 = HexDigit(str[num6 + 4])) != -1) && ((num5 = HexDigit(str[num6 + 5])) != -1)))
|
|
{
|
|
ch = (char)((((num2 << 12) + (num3 << 8)) + (num4 << 4)) + num5);
|
|
num6 += 5;
|
|
}
|
|
else if ((((num6 + 2) < length) && ((num2 = HexDigit(str[num6 + 1])) != -1)) && ((num3 = HexDigit(str[num6 + 2])) != -1))
|
|
{
|
|
ch = (char)((num2 << 4) + num3);
|
|
num6 += 2;
|
|
}
|
|
}
|
|
builder.Append(ch);
|
|
}
|
|
return builder.ToString();
|
|
}
|
|
/// <summary>
|
|
/// 加密
|
|
/// </summary>
|
|
/// <param name="string"></param>
|
|
/// <returns></returns>
|
|
public static string Escape(object @string)
|
|
{
|
|
string str = Convert.ToString(@string);
|
|
string str2 = "0123456789ABCDEF";
|
|
int length = str.Length;
|
|
StringBuilder builder = new StringBuilder(length * 2);
|
|
int num3 = -1;
|
|
while (++num3 < length)
|
|
{
|
|
char ch = str[num3];
|
|
int num2 = ch;
|
|
if ((((0x41 > num2) || (num2 > 90)) && ((0x61 > num2) || (num2 > 0x7a))) && ((0x30 > num2) || (num2 > 0x39)))
|
|
{
|
|
switch (ch)
|
|
{
|
|
case '@':
|
|
case '*':
|
|
case '_':
|
|
case '+':
|
|
case '-':
|
|
case '.':
|
|
case '/':
|
|
goto Label_0125;
|
|
}
|
|
builder.Append('%');
|
|
if (num2 < 0x100)
|
|
{
|
|
builder.Append(str2[num2 / 0x10]);
|
|
ch = str2[num2 % 0x10];
|
|
}
|
|
else
|
|
{
|
|
builder.Append('u');
|
|
builder.Append(str2[(num2 >> 12) % 0x10]);
|
|
builder.Append(str2[(num2 >> 8) % 0x10]);
|
|
builder.Append(str2[(num2 >> 4) % 0x10]);
|
|
ch = str2[num2 % 0x10];
|
|
}
|
|
}
|
|
Label_0125:
|
|
builder.Append(ch);
|
|
}
|
|
return builder.ToString();
|
|
}
|
|
private static bool ValidateUrlEncodingParameters(byte[] bytes, int offset, int count)
|
|
{
|
|
if ((bytes == null) && (count == 0))
|
|
{
|
|
return false;
|
|
}
|
|
if (bytes == null)
|
|
{
|
|
throw new ArgumentNullException("bytes");
|
|
}
|
|
if ((offset < 0) || (offset > bytes.Length))
|
|
{
|
|
throw new ArgumentOutOfRangeException("offset");
|
|
}
|
|
if ((count < 0) || ((offset + count) > bytes.Length))
|
|
{
|
|
throw new ArgumentOutOfRangeException("count");
|
|
}
|
|
return true;
|
|
}
|
|
private static bool IsNonAsciiByte(byte b)
|
|
{
|
|
if (b < 0x7f)
|
|
{
|
|
return (b < 0x20);
|
|
}
|
|
return true;
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="bytes"></param>
|
|
/// <param name="offset"></param>
|
|
/// <param name="count"></param>
|
|
/// <param name="alwaysCreateNewReturnValue"></param>
|
|
/// <returns></returns>
|
|
public static byte[] UrlEncodeNonAscii(byte[] bytes, int offset, int count, bool alwaysCreateNewReturnValue)
|
|
{
|
|
if (!ValidateUrlEncodingParameters(bytes, offset, count))
|
|
{
|
|
return null;
|
|
}
|
|
int num = 0;
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
if (IsNonAsciiByte(bytes[offset + i]))
|
|
{
|
|
num++;
|
|
}
|
|
}
|
|
if (!alwaysCreateNewReturnValue && (num == 0))
|
|
{
|
|
return bytes;
|
|
}
|
|
byte[] buffer = new byte[count + (num * 2)];
|
|
int num3 = 0;
|
|
for (int j = 0; j < count; j++)
|
|
{
|
|
byte b = bytes[offset + j];
|
|
if (IsNonAsciiByte(b))
|
|
{
|
|
buffer[num3++] = 0x25;
|
|
buffer[num3++] = (byte)IntToHex((b >> 4) & 15);
|
|
buffer[num3++] = (byte)IntToHex(b & 15);
|
|
}
|
|
else
|
|
{
|
|
buffer[num3++] = b;
|
|
}
|
|
}
|
|
return buffer;
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="str"></param>
|
|
/// <param name="e"></param>
|
|
/// <returns></returns>
|
|
public static string UrlEncodeNonAscii(string str, Encoding e)
|
|
{
|
|
if (string.IsNullOrEmpty(str))
|
|
{
|
|
return str;
|
|
}
|
|
if (e == null)
|
|
{
|
|
e = Encoding.UTF8;
|
|
}
|
|
byte[] bytes = e.GetBytes(str);
|
|
byte[] buffer2 = UrlEncodeNonAscii(bytes, 0, bytes.Length, false);
|
|
return Encoding.ASCII.GetString(buffer2);
|
|
}
|
|
/// <summary>
|
|
/// url加密,Unicode
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
/// <param name="ignoreAscii"></param>
|
|
/// <returns></returns>
|
|
public static string UrlEncodeUnicode(string value, bool ignoreAscii)
|
|
{
|
|
if (value == null)
|
|
{
|
|
return null;
|
|
}
|
|
int length = value.Length;
|
|
StringBuilder builder = new StringBuilder(length);
|
|
for (int i = 0; i < length; i++)
|
|
{
|
|
char ch = value[i];
|
|
if ((ch & 0xff80) == 0)
|
|
{
|
|
if (ignoreAscii || IsUrlSafeChar(ch))
|
|
{
|
|
builder.Append(ch);
|
|
}
|
|
else if (ch == ' ')
|
|
{
|
|
builder.Append('+');
|
|
}
|
|
else
|
|
{
|
|
builder.Append('%');
|
|
builder.Append(IntToHex((ch >> 4) & '\x000f'));
|
|
builder.Append(IntToHex(ch & '\x000f'));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
builder.Append("%u");
|
|
builder.Append(IntToHex((ch >> 12) & '\x000f'));
|
|
builder.Append(IntToHex((ch >> 8) & '\x000f'));
|
|
builder.Append(IntToHex((ch >> 4) & '\x000f'));
|
|
builder.Append(IntToHex(ch & '\x000f'));
|
|
}
|
|
}
|
|
return builder.ToString();
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="ch"></param>
|
|
/// <returns></returns>
|
|
public static bool IsUrlSafeChar(char ch)
|
|
{
|
|
if ((((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z'))) || ((ch >= '0') && (ch <= '9')))
|
|
{
|
|
return true;
|
|
}
|
|
switch (ch)
|
|
{
|
|
case '(':
|
|
case ')':
|
|
case '*':
|
|
case '-':
|
|
case '.':
|
|
case '_':
|
|
case '!':
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="n"></param>
|
|
/// <returns></returns>
|
|
public static char IntToHex(int n)
|
|
{
|
|
if (n <= 9)
|
|
{
|
|
return (char)(n + 0x30);
|
|
}
|
|
return (char)((n - 10) + 0x61);
|
|
}
|
|
/// <summary>
|
|
/// Html解码,将html里未转义成功的重新转义。
|
|
/// </summary>
|
|
/// <param name="str"></param>
|
|
/// <returns></returns>
|
|
public static string ConvertHtmlInner(string str)
|
|
{
|
|
return System.Web.HttpUtility.HtmlDecode(str);
|
|
}
|
|
}
|
|
}
|