RaUI/Source/MyDb/RyWeb/WebDecode.cs
鑫Intel c3d4ddf574 ### 2021-07-29更新
------
#### MyDbV4   V3.0.2107.2901
- *.[新增]新增支持计算文件MD5。
- *.[新增]部分DataProvider功能移植到DbExtension里,增加扩展性。
- *.[新增]UnixTimeToDateTime和JSTimeToDateTime新增支持long参数。
- *.[合并]合并RyWeb项目到MyDb里。

#### ryControlsV4    V3.0.2107.2901
  -  *.[改进]优化减少大量IDE警告和消息。
2021-07-29 17:09:32 +08:00

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);
}
}
}