ns-ext/src/backend/NSExt/Extensions/StringExtensions.cs
nsnail b32fe597dd
perf: 支持.net9 (#21)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-25 17:01:15 +08:00

629 lines
19 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.

// ReSharper disable UnusedMember.Global
// ReSharper disable MemberCanBePrivate.Global
#pragma warning disable CA1720
using System.Security.Cryptography;
using System.Text.Json;
using System.Web;
using NSExt.Constant;
namespace NSExt.Extensions;
/// <summary>
/// StringExtensions
/// </summary>
#pragma warning disable CodeLinesAnalyzer
public static class StringExtensions
{
/// <summary>
/// aes加密
/// </summary>
/// <param name="me">me</param>
/// <param name="key">密钥</param>
public static string Aes(this string me, string key)
{
using var aes = System.Security.Cryptography.Aes.Create();
aes.Padding = PaddingMode.PKCS7;
aes.Mode = CipherMode.ECB;
aes.Key = key.Hex();
using var encryptor = aes.CreateEncryptor();
var bytes = me.Hex();
var decrypted = encryptor.TransformFinalBlock(bytes, 0, bytes.Length);
return decrypted.Base64();
}
/// <summary>
/// aes解密
/// </summary>
/// <param name="me">me</param>
/// <param name="key">密钥</param>
public static string AesDe(this string me, string key)
{
using var aes = System.Security.Cryptography.Aes.Create();
aes.Padding = PaddingMode.PKCS7;
aes.Mode = CipherMode.ECB;
aes.Key = key.Hex();
using var encryptor = aes.CreateDecryptor();
var bytes = me.Base64De();
var decrypted = encryptor.TransformFinalBlock(bytes, 0, bytes.Length);
return decrypted.HexDe();
}
/// <summary>
/// base64编码
/// </summary>
/// <param name="me">me</param>
/// <param name="e">字符串的编码方式</param>
/// <returns>编码后的base64字符串</returns>
public static string Base64(this string me, Encoding e)
{
return e.GetBytes(me).Base64();
}
/// <summary>
/// base64解码
/// </summary>
/// <param name="me">me</param>
/// <returns>解码后的原始字节数组</returns>
public static byte[] Base64De(this string me)
{
return Convert.FromBase64String(me);
}
/// <summary>
/// base64解码
/// </summary>
/// <param name="me">me</param>
/// <param name="e">字符串的编码方式</param>
/// <returns>解码后的原始字符串</returns>
public static string Base64De(this string me, Encoding e)
{
return e.GetString(me.Base64De());
}
/// <summary>
/// 将易于web传输的base64web字符串转换为原生base64
/// </summary>
/// <returns>原生base64</returns>
public static string Base64Sys(this string me)
{
return me.Replace("-", "+").Replace("_", "/").Replace(".", "=");
}
/// <summary>
/// 将原生base64字符串转换成易于web传输的字符串
/// </summary>
/// <returns>易于web传输的字符串</returns>
public static string Base64Web(this string me)
{
return me.Replace("+", "-").Replace("/", "_").Replace("=", ".");
}
/// <summary>
/// 将字符串转换成日期对象
/// </summary>
/// <param name="me">me</param>
/// <returns>转换后的日期对象</returns>
public static DateTime DateTime(this string me)
{
return System.DateTime.Parse(me, CultureInfo.CurrentCulture);
}
/// <summary>
/// 将字符串转换成日期对象
/// </summary>
/// <param name="me">me</param>
/// <param name="format">日期格式</param>
/// <returns>转换后的日期对象</returns>
public static DateTime DateTimeExact(this string me, string format)
{
return System.DateTime.ParseExact(me, format, CultureInfo.CurrentCulture);
}
/// <summary>
/// 将字符串转换成日期对象
/// </summary>
/// <param name="me">me</param>
/// <param name="format">日期格式</param>
/// <param name="def">转换失败时返回的日期对象</param>
/// <returns>转换后的日期对象</returns>
public static DateTime DateTimeExactTry(this string me, string format, DateTime def)
{
return !System.DateTime.TryParseExact(me, format, CultureInfo.CurrentCulture, DateTimeStyles.None, out var ret)
? def
: ret;
}
/// <summary>
/// 将字符串转换成日期对象
/// </summary>
/// <param name="me">me</param>
/// <param name="def">转换失败时返回的日期对象</param>
/// <returns>转换后的日期对象</returns>
public static DateTime DateTimeTry(this string me, DateTime def)
{
return !System.DateTime.TryParse(me, CultureInfo.InvariantCulture, DateTimeStyles.None, out var ret)
? def
: ret;
}
/// <summary>
/// string to decimal
/// </summary>
/// <param name="me">me</param>
/// <returns>decimal</returns>
public static decimal Dec(this string me)
{
return decimal.Parse(me, CultureInfo.CurrentCulture);
}
/// <summary>
/// 尝试将字符串转为decimal
/// </summary>
/// <param name="me">me</param>
/// <param name="def">转换失败后返回的默认值</param>
/// <returns>转换后的decimal</returns>
public static decimal DecTry(this string me, decimal def)
{
return !decimal.TryParse(me, out var ret) ? def : ret;
}
/// <summary>
/// string to double
/// </summary>
/// <param name="me">me</param>
/// <returns>Int32</returns>
public static double Double(this string me)
{
return double.Parse(me, CultureInfo.CurrentCulture);
}
/// <summary>
/// 将字符串转换成枚举对象
/// </summary>
public static T Enum<T>(this string name)
where T : Enum
{
return (T)System.Enum.Parse(typeof(T), name, true);
}
/// <summary>
/// 将字符串转换成枚举对象
/// </summary>
public static T EnumTry<T>(this string name, T def)
where T : Enum
{
return !System.Enum.TryParse(typeof(T), name, out var ret) ? def : (T)ret;
}
/// <summary>
/// string to float
/// </summary>
/// <param name="me">me</param>
/// <returns>Int32</returns>
public static float Float(this string me)
{
return float.Parse(me, CultureInfo.CurrentCulture);
}
/// <summary>
/// 将字符串转为guid
/// </summary>
/// <param name="me">me</param>
public static Guid Guid(this string me)
{
return System.Guid.Parse(me);
}
/// <summary>
/// 将字符串转换成guid
/// </summary>
/// <param name="me">me</param>
/// <param name="def">转换失败的返回值</param>
public static Guid Guid(this string me, Guid def)
{
return System.Guid.TryParse(me, out var ret) ? ret : def;
}
/// <summary>
/// 将字符串转换成字节数组形式
/// </summary>
/// <param name="me">me</param>
/// <param name="e">字符串使用的编码</param>
/// <returns>字节数组</returns>
public static byte[] Hex(this string me, Encoding e)
{
return e.GetBytes(me);
}
/// <summary>
/// 将字符串转换成字节数组形式
/// </summary>
/// <param name="me">me</param>
/// <returns>字节数组</returns>
public static byte[] Hex(this string me)
{
return me.Hex(Encoding.UTF8);
}
/// <summary>
/// 对一个字符串进行sha1 hash运算
/// </summary>
/// <param name="me">me</param>
/// <param name="secret">密钥</param>
/// <param name="e">使用的编码</param>
/// <returns>hash摘要的16进制文本形式无连字符小写</returns>
public static string HmacSha1(this string me, string secret, Encoding e)
{
#pragma warning disable CA5350
using var hmacSha1 = new HMACSHA1(e.GetBytes(secret));
#pragma warning restore CA5350
#if NET9_0_OR_GREATER
return Convert.ToHexStringLower(hmacSha1.ComputeHash(e.GetBytes(me)));
#else
return BitConverter.ToString(hmacSha1.ComputeHash(e.GetBytes(me)))
.Replace("-", string.Empty)
.ToLower(CultureInfo.CurrentCulture);
#endif
}
/// <summary>
/// html编码
/// </summary>
public static string Html(this string me)
{
return HttpUtility.HtmlEncode(me);
}
/// <summary>
/// 解码html编码
/// </summary>
/// <param name="me">me</param>
/// <returns>解码后的原始字符串</returns>
public static string HtmlDe(this string me)
{
return HttpUtility.HtmlDecode(me);
}
/// <summary>
/// string to Int32
/// </summary>
/// <param name="me">me</param>
/// <returns>Int32</returns>
public static int Int32(this string me)
{
return int.Parse(me, CultureInfo.CurrentCulture);
}
/// <summary>
/// 尝试将字符串转为int32
/// </summary>
/// <param name="me">me</param>
/// <param name="def">转换失败后返回的默认值</param>
/// <returns>转换后的int32</returns>
public static int Int32Try(this string me, int def)
{
return !int.TryParse(me, out var ret) ? def : ret;
}
/// <summary>
/// string to Int64
/// </summary>
/// <param name="me">me</param>
/// <returns>Int64</returns>
public static long Int64(this string me)
{
return long.Parse(me, CultureInfo.CurrentCulture);
}
/// <summary>
/// 尝试将字符串转为int64
/// </summary>
/// <param name="me">me</param>
/// <param name="def">转换失败后返回的默认值</param>
/// <returns>转换后的int64</returns>
public static long Int64Try(this string me, long def)
{
return !long.TryParse(me, out var ret) ? def : ret;
}
/// <summary>
/// ipv4格式转int32格式
/// </summary>
public static int IpV4ToInt32(this string me)
{
return BitConverter.ToInt32(me.Split('.').Select(byte.Parse).Reverse().ToArray(), 0);
}
/// <summary>
/// 是否base64字符串
/// </summary>
/// <param name="me">me</param>
public static bool IsBase64String(this string me)
{
// 一个合法的Base64有着以下特征
// 字符串的长度为4的整数倍。
// 字符串的符号取值只能在A -Z, a -z, 0 -9, +, /, =共计65个字符中且 = 如果出现就必须在结尾出现。
if (!me.All(x => x.IsBase64Character())) {
return false;
}
if (me.Length % 4 != 0) {
return false;
}
var firstEqualSignPos = me.IndexOf('=');
if (firstEqualSignPos < 0) {
return true;
}
var lastEqualSignPos = me.LastIndexOf('=');
return lastEqualSignPos == me.Length - 1 && me[firstEqualSignPos..lastEqualSignPos].All(x => x == '=');
}
/// <summary>
/// 是否json字符串
/// </summary>
/// <param name="me">me</param>
public static bool IsJsonString(this string me)
{
if (me.NullOrEmpty()) {
return false;
}
try {
_ = JsonDocument.Parse(me);
}
catch {
return false;
}
return true;
}
/// <summary>
/// 中文姓名打马赛克
/// </summary>
public static string MaskChineseName(this string me)
{
return me.Length == 2 ? "*" + me[1..] : me[..1] + "*" + me[^1..];
}
/// <summary>
/// 对一个手机号进行掩码处理
/// </summary>
/// <param name="me">me</param>
/// <returns>掩码后的手机号</returns>
public static string MaskMobile(this string me)
{
return Regexes.RegexMobile.Replace(me, "$1****$2");
}
/// <summary>
/// 对一个字符串进行md5hash运算
/// </summary>
/// <param name="me">me</param>
/// <param name="e">字符串使用的编码</param>
/// <returns>hash摘要的16进制文本形式无连字符小写</returns>
public static string Md5(this string me, Encoding e)
{
#pragma warning disable CA5351
#if NET9_0_OR_GREATER
return Convert.ToHexStringLower(MD5.HashData(e.GetBytes(me)));
#else
return BitConverter.ToString(MD5.HashData(e.GetBytes(me)))
#pragma warning restore CA5351
.Replace("-", string.Empty)
.ToLower(CultureInfo.CurrentCulture);
#endif
}
/// <summary>
/// 判断字符串是否为null或不存在子元素如果为集合对象如果为空返回指定的默认值否则返回字符串本身
/// </summary>
/// <param name="me">me</param>
/// <param name="defVal">指定的默认值</param>
/// <returns>如果为空,返回指定的默认值,否则返回字符串本身</returns>
public static string NullOrEmpty(this string me, string defVal)
{
return me.AsEnumerable().NullOrEmpty() ? defVal : me;
}
/// <summary>
/// null或空白字符
/// </summary>
public static bool NullOrWhiteSpace(this string me)
{
return string.IsNullOrWhiteSpace(me);
}
/// <summary>
/// 反序列化一个文件获得指定类型的数据对象
/// </summary>
/// <param name="me">me</param>
/// <param name="options">序列化选项</param>
/// <returns>反序列化后生成的对象</returns>
public static T Object<T>(this string me, JsonSerializerOptions options = null)
{
return JsonSerializer.Deserialize<T>(me, options);
}
/// <summary>
/// 反序列化一个文件获得指定类型的数据对象
/// </summary>
/// <param name="me">me</param>
/// <param name="type">实际类型</param>
/// <param name="options">序列化选项</param>
/// <returns>反序列化后生成的对象</returns>
public static object Object(this string me, Type type, JsonSerializerOptions options = null)
{
return JsonSerializer.Deserialize(me, type, options);
}
/// <summary>
/// 生成密码
/// </summary>
/// <param name="me">me</param>
/// <returns>密文</returns>
public static string Pwd(this string me)
{
return me.Md5Hmac(me.Md5(Encoding.UTF8), Encoding.UTF8);
}
/// <summary>
/// 移除字符串中的html标签
/// </summary>
/// <param name="me">me</param>
/// <returns>处理之后的字符串</returns>
public static string RemoveHtmlTag(this string me)
{
return Regexes.RegexHtmlTag.Replace(me, string.Empty);
}
/// <summary>
/// 删除换行符
/// </summary>
public static string RemoveWrapped(this string me)
{
return me.Replace("\r", string.Empty).Replace("\n", string.Empty);
}
/// <summary>
/// 对一个字符串进行sha1 hash运算
/// </summary>
/// <param name="me">me</param>
/// <param name="e">字符串使用的编码</param>
/// <returns>hash摘要的16进制文本形式无连字符小写</returns>
public static string Sha1(this string me, Encoding e)
{
#pragma warning disable CA5350
#if NET9_0_OR_GREATER
return Convert.ToHexStringLower(SHA1.HashData(e.GetBytes(me)));
#else
return BitConverter.ToString(SHA1.HashData(e.GetBytes(me)))
#pragma warning restore CA5350
.Replace("-", string.Empty)
.ToLower(CultureInfo.CurrentCulture);
#endif
}
/// <summary>
/// 蛇形命名
/// </summary>
public static string SnakeCase(this string me)
{
return Regexes.RegexUpLetter.Replace(me, "-$1").ToLower(CultureInfo.InvariantCulture).TrimStart('-');
}
/// <summary>
/// 截取指定长度的字符串代替substring
/// </summary>
public static string Sub(this string me, int startIndex, int length)
{
if (startIndex + length > me.Length) {
length = me.Length - startIndex;
}
return me.Substring(startIndex, length);
}
/// <summary>
/// 纯文本字符串转html
/// </summary>
public static string Text2Html(this string me)
{
return $"<pre>{me}</pre>";
}
/// <summary>
/// 首字母小写
/// </summary>
public static string ToLowerCamelCase(this string me)
{
return string.IsNullOrWhiteSpace(me)
? me
: string.Concat( //
me[0].ToString(CultureInfo.InvariantCulture).ToLowerInvariant(), me.AsSpan(1));
}
/// <summary>
/// 首字母大写
/// </summary>
public static string ToUpperCamelCase(this string me)
{
return string.IsNullOrWhiteSpace(me) ? me : string.Concat(me[0].ToString().ToUpperInvariant(), me.AsSpan(1));
}
/// <summary>
/// 将连续多个空格替换成一个空格
/// </summary>
public static string TrimSpaces(this string me)
{
var ret = me.Replace(" ", " ");
// ReSharper disable once TailRecursiveCall
return ret == me ? ret : ret.TrimSpaces();
}
/// <summary>
/// 将\ux0000 、 %u0000 、 &amp;#x0000; 编码转换成可读字符串
/// </summary>
public static string UnicodeDe(this string me)
{
const string replacement = "&#x$1;";
if (me.Contains(@"\u")) {
return Regexes.RegexBacksLantUnicode.Replace(me, replacement).HtmlDe();
}
// ReSharper disable once ConvertIfStatementToReturnStatement
#pragma warning disable IDE0046
if (me.Contains("%u")) {
#pragma warning restore IDE0046
return Regexes.RegexPercentUnicode.Replace(me, replacement).HtmlDe();
}
return me.HtmlDe();
}
/// <summary>
/// url编码
/// </summary>
/// <param name="me">me</param>
/// <returns>url编码后的字符串</returns>
public static string Url(this string me)
{
return Uri.EscapeDataString(me);
}
/// <summary>
/// 解码url编码
/// </summary>
/// <param name="me">me</param>
/// <returns>解码后的原始字符串</returns>
public static string UrlDe(this string me)
{
return Uri.UnescapeDataString(me);
}
/// <summary>
/// MD5 hmac编码
/// </summary>
/// <param name="me">me</param>
/// <param name="key">密钥</param>
/// <param name="e">字符串使用的编码</param>
/// <returns>hash摘要的16进制文本形式无连字符小写</returns>
private static string Md5Hmac(this string me, string key, Encoding e)
{
#pragma warning disable CA5351
using var md5Hmac = new HMACMD5(e.GetBytes(key));
#pragma warning restore CA5351
#if NET9_0_OR_GREATER
return Convert.ToHexStringLower(md5Hmac.ComputeHash(e.GetBytes(me)));
#else
return BitConverter.ToString(md5Hmac.ComputeHash(e.GetBytes(me)))
.Replace("-", string.Empty)
.ToLower(CultureInfo.CurrentCulture);
#endif
}
}
#pragma warning restore CodeLinesAnalyzer