Files
g.hnyhua.cn/COSXML/Utils/URLEncodeUtils.cs
2026-02-07 15:48:27 +08:00

102 lines
3.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
/**
* Copyright (c) 2018 Tencent Cloud. All rights reserved.
* 11/5/2018 5:40:47 PM
* bradyxiao
*/
namespace COSXML.Utils
{
/**
* URL Encode:
* 可分为绝对不需要编码的字符:[a~z][A~A][0~9][._-~]
* 特殊字符需要视情况而言:!*'();:@&=+$,/?#[]
* 空字符用+或者%20代替
* 汉字绝地需要编码
* 因此针对完整URL则要分块进行编码path块query块fragment块host块
* path块需要以'/'进行分割,即 '/' 不需要编码,其它均需要编码
* query块需要以'&'分割一对对key=valuekey 和 value 需要编码, "="不编码
* fragment全部进行编码
* URL Decode:
* 不需要判断是否是特殊字符,因为其解码规则很简单,直接根据内容中是否出现%来判断是否需要解码,
* 还是直接输出:若出现了%,则连续读出其后两位进行解码;反之,直接输出
*/
public sealed class URLEncodeUtils
{
//只有字母和数字[0-9a-zA-Z]、一些特殊符号"-_.!*~',以及某些保留字才可以不经过编码直接用于URL。"
public const string URLAllowChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";
/// <summary>
/// 针对 URL 中 path 编码,则需要先将其按照 '/'分割,然后进行逐个块进行 value 编码
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static string EncodePathOfURL(string path)
{
if (String.IsNullOrEmpty(path)) return String.Empty;
char separator = '/';
int start = 0, length = path.Length;
int index = path.IndexOf(separator, start);
StringBuilder result = new StringBuilder();
while (index != -1 && start < length)
{
if (start != index)
{
result.Append(Encode(path.Substring(start, index - start)));
}
result.Append(separator);
start = index + 1;
index = path.IndexOf(separator, start);
}
if(start < length) result.Append(Encode(path.Substring(start)));
return result.ToString();
}
public static string Encode(string value)
{
return Encode(value, Encoding.UTF8);
}
/// <summary>
/// 针对单个value则只需满足 URLAllowChars 不需要编码即可.
/// urlEncode: 转为一个byte -> 转为两个16进制 -> 前面加上 %
/// </summary>
/// <param name="value"></param>
/// <param name="encoding"></param>
/// <returns></returns>
public static string Encode(string value, Encoding encoding)
{
if (String.IsNullOrEmpty(value)) return String.Empty;
StringBuilder result = new StringBuilder(value.Length * 2); // %xy%xy
byte[] strToBytes = encoding.GetBytes(value);
foreach(byte b in strToBytes)
{
char ch = (char)b;
if(URLAllowChars.IndexOf(ch) != -1)
{
result.Append(ch);
}
else
{
result.Append('%').Append(String.Format(CultureInfo.InvariantCulture, "{0:X2}", (int)b));
}
}
return result.ToString();
}
/// <summary>
/// 解码比较统一,此处借用 Uri 来实现
/// </summary>
/// <param name="valueEncode"></param>
/// <returns></returns>
public static string Decode(string valueEncode)
{
if (String.IsNullOrEmpty(valueEncode)) return String.Empty;
valueEncode.Replace('+', ' ');
return Uri.UnescapeDataString(valueEncode);
}
}
}