diff --git a/.editorconfig b/.editorconfig
index 0c64ba7..e0d113c 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -19,6 +19,10 @@ indent_size = 2 # 对于 JSON 和 YAML 文件,缩进大小为 2 个空格
[*.cs]
dotnet_analyzer_diagnostic.severity = warning # 设置 C# 文件中所有 dotnet_analyzer_diagnostic 的严重性级别为 warning
+[*.g.cs]
+dotnet_analyzer_diagnostic.severity = none # 禁用所有代码分析规则
+
+
# ReSharper properties
resharper_align_linq_query = true # 启用对LINQ查询的对齐
resharper_align_multiline_argument = true # 启用多行参数的对齐
diff --git a/Directory.Build.props b/Directory.Build.props
index 00d57ad..9c56cc6 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -17,7 +17,7 @@
preview
beta
v
- CA1707;IDE0005;IDE0008;IDE0010;IDE0028;IDE0055;IDE0160;IDE0300;IDE0305;RCS1141;RCS1142;RCS1181;S101;S1121;S1135;S125;S2094;S3604;S4663;SYSLIB1045;SA1010;RCS1123;SA1407;IDE0048;S1075;S3928
+ CA1707;CA1720;CA5350;CA5351;IDE0005;IDE0008;IDE0010;IDE0028;IDE0048;IDE0055;IDE0160;IDE0300;IDE0305;RCS1123;RCS1141;RCS1142;RCS1181;S101;S1075;S1121;S1135;S125;S2094;S3604;S3928;S4663;SA1010;SA1407;SYSLIB1045
NSExt
git
https://github.com/nsnail/NSExt.git
diff --git a/package.json b/package.json
index 8c324cd..f067e31 100644
--- a/package.json
+++ b/package.json
@@ -11,4 +11,4 @@
"path": "node_modules/cz-git"
}
}
-}
+}
\ No newline at end of file
diff --git a/src/backend/NSExt/Extensions/StringExtensions.cs b/src/backend/NSExt/Extensions/StringExtensions.cs
index fa4c2f1..c99a60b 100644
--- a/src/backend/NSExt/Extensions/StringExtensions.cs
+++ b/src/backend/NSExt/Extensions/StringExtensions.cs
@@ -1,10 +1,10 @@
-// ReSharper disable UnusedMember.Global
-// ReSharper disable MemberCanBePrivate.Global
-
-#pragma warning disable CA1720
+using System.Numerics;
+using System.Reflection;
using System.Security.Cryptography;
using System.Text.Json;
using System.Web;
+using Microsoft.CodeAnalysis.CSharp.Scripting;
+using Microsoft.CodeAnalysis.Scripting;
using NSExt.Constant;
namespace NSExt.Extensions;
@@ -12,9 +12,11 @@ namespace NSExt.Extensions;
///
/// StringExtensions
///
-#pragma warning disable CodeLinesAnalyzer
-public static class StringExtensions
+public static partial class StringExtensions
{
+ private const string _CHARACTERS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+ private static readonly Regex _regexIpV4 = RegexIpV4();
+
///
/// aes加密
///
@@ -24,11 +26,11 @@ public static class StringExtensions
{
using var aes = System.Security.Cryptography.Aes.Create();
aes.Padding = PaddingMode.PKCS7;
- aes.Mode = CipherMode.ECB;
- aes.Key = key.Hex();
+ 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);
+ var bytes = me.Hex();
+ var decrypted = encryptor.TransformFinalBlock(bytes, 0, bytes.Length);
return decrypted.Base64();
}
@@ -41,14 +43,72 @@ public static class StringExtensions
{
using var aes = System.Security.Cryptography.Aes.Create();
aes.Padding = PaddingMode.PKCS7;
- aes.Mode = CipherMode.ECB;
- aes.Key = key.Hex();
+ 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);
+ var bytes = me.Base64De();
+ var decrypted = encryptor.TransformFinalBlock(bytes, 0, bytes.Length);
return decrypted.HexDe();
}
+ ///
+ /// 将指定的输入字符串进行Base62解码
+ ///
+ /// ArgumentException
+ public static string Base62Decode(this string me)
+ {
+ BigInteger result = 0;
+
+ foreach (var index in me.Select(c => _CHARACTERS.IndexOf(c)))
+ {
+ if (index < 0)
+ {
+ throw new ArgumentException("Invalid character in Base62 string.");
+ }
+
+ result = result * 62 + index;
+ }
+
+ // Convert BigInteger back to byte array and then to string
+ var bytes = result.ToByteArray();
+
+ // Handle the sign bit
+ if (bytes[^1] == 0)
+ {
+ Array.Resize(ref bytes, bytes.Length - 1);
+ }
+
+ return Encoding.UTF8.GetString(bytes);
+ }
+
+ ///
+ /// 将指定的输入字符串进行Base62编码
+ ///
+ public static string Base62Encode(this string me)
+ {
+ // Convert string to byte array
+ var bytes = Encoding.UTF8.GetBytes(me);
+
+ // Convert byte array to BigInteger for easier processing
+ var bigInteger = new BigInteger(bytes);
+
+ if (bigInteger == 0)
+ {
+ return _CHARACTERS[0].ToString();
+ }
+
+ var result = new StringBuilder();
+
+ while (bigInteger > 0)
+ {
+ var remainder = (int)(bigInteger % 62);
+ bigInteger /= 62;
+ _ = result.Insert(0, _CHARACTERS[remainder]);
+ }
+
+ return result.ToString();
+ }
+
///
/// base64编码
///
@@ -81,6 +141,22 @@ public static class StringExtensions
return e.GetString(me.Base64De());
}
+ ///
+ /// 解码避免转义的Base64
+ ///
+ public static string Base64InUrlDecode(this string me)
+ {
+ return me.Replace("-", "+").Replace("_", "/");
+ }
+
+ ///
+ /// 编码避免转义的Base64
+ ///
+ public static string Base64InUrlEncode(this string me)
+ {
+ return me.Replace("+", "-").Replace("/", "_");
+ }
+
///
/// 将易于web传输的base64web字符串转换为原生base64
///
@@ -99,6 +175,14 @@ public static class StringExtensions
return me.Replace("+", "-").Replace("/", "_").Replace("=", ".");
}
+ ///
+ /// 计算Crc32
+ ///
+ public static int Crc32(this string me)
+ {
+ return BitConverter.ToInt32(System.IO.Hashing.Crc32.Hash(Encoding.UTF8.GetBytes(me)));
+ }
+
///
/// 将字符串转换成日期对象
///
@@ -129,9 +213,7 @@ public static class StringExtensions
/// 转换后的日期对象
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;
+ return !System.DateTime.TryParseExact(me, format, CultureInfo.CurrentCulture, DateTimeStyles.None, out var ret) ? def : ret;
}
///
@@ -142,9 +224,7 @@ public static class StringExtensions
/// 转换后的日期对象
public static DateTime DateTimeTry(this string me, DateTime def)
{
- return !System.DateTime.TryParse(me, CultureInfo.InvariantCulture, DateTimeStyles.None, out var ret)
- ? def
- : ret;
+ return !System.DateTime.TryParse(me, CultureInfo.InvariantCulture, DateTimeStyles.None, out var ret) ? def : ret;
}
///
@@ -196,6 +276,15 @@ public static class StringExtensions
return !System.Enum.TryParse(typeof(T), name, out var ret) ? def : (T)ret;
}
+ ///
+ /// 执行C#代码
+ ///
+ public static Task ExecuteCSharpCodeAsync(this string me, Assembly[] assemblies, params string[] importNamespaces)
+ {
+ // 使用 Roslyn 编译并执行代码
+ return CSharpScript.EvaluateAsync(me, ScriptOptions.Default.WithReferences(assemblies).WithImports(importNamespaces));
+ }
+
///
/// string to float
///
@@ -255,16 +344,13 @@ public static class StringExtensions
/// hash摘要的16进制文本形式(无连字符小写)
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
+
+#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
+#else
+ return BitConverter.ToString(hmacSha1.ComputeHash(e.GetBytes(me))).Replace("-", string.Empty).ToLower(CultureInfo.CurrentCulture);
+#endif
}
///
@@ -344,16 +430,19 @@ public static class StringExtensions
// 一个合法的Base64,有着以下特征:
// 字符串的长度为4的整数倍。
// 字符串的符号取值只能在A -Z, a -z, 0 -9, +, /, =共计65个字符中,且 = 如果出现就必须在结尾出现。
- if (!me.All(x => x.IsBase64Character())) {
+ if (!me.All(x => x.IsBase64Character()))
+ {
return false;
}
- if (me.Length % 4 != 0) {
+ if (me.Length % 4 != 0)
+ {
return false;
}
var firstEqualSignPos = me.IndexOf('=');
- if (firstEqualSignPos < 0) {
+ if (firstEqualSignPos < 0)
+ {
return true;
}
@@ -361,20 +450,31 @@ public static class StringExtensions
return lastEqualSignPos == me.Length - 1 && me[firstEqualSignPos..lastEqualSignPos].All(x => x == '=');
}
+ ///
+ /// 是否IPV4地址
+ ///
+ public static bool IsIpV4(this string me)
+ {
+ return _regexIpV4.IsMatch(me);
+ }
+
///
/// 是否json字符串
///
/// me
public static bool IsJsonString(this string me)
{
- if (me.NullOrEmpty()) {
+ if (me.NullOrEmpty())
+ {
return false;
}
- try {
+ try
+ {
_ = JsonDocument.Parse(me);
}
- catch {
+ catch
+ {
return false;
}
@@ -407,15 +507,13 @@ public static class StringExtensions
/// hash摘要的16进制文本形式(无连字符小写)
public static string Md5(this string me, Encoding e)
{
- #pragma warning disable CA5351
- #if NET9_0_OR_GREATER
+#if NET9_0_OR_GREATER
return Convert.ToHexStringLower(MD5.HashData(e.GetBytes(me)));
- #else
+#else
return BitConverter.ToString(MD5.HashData(e.GetBytes(me)))
- #pragma warning restore CA5351
- .Replace("-", string.Empty)
- .ToLower(CultureInfo.CurrentCulture);
- #endif
+ .Replace("-", string.Empty)
+ .ToLower(CultureInfo.CurrentCulture);
+#endif
}
///
@@ -496,15 +594,13 @@ public static class StringExtensions
/// hash摘要的16进制文本形式(无连字符小写)
public static string Sha1(this string me, Encoding e)
{
- #pragma warning disable CA5350
- #if NET9_0_OR_GREATER
+#if NET9_0_OR_GREATER
return Convert.ToHexStringLower(SHA1.HashData(e.GetBytes(me)));
- #else
+#else
return BitConverter.ToString(SHA1.HashData(e.GetBytes(me)))
- #pragma warning restore CA5350
- .Replace("-", string.Empty)
- .ToLower(CultureInfo.CurrentCulture);
- #endif
+ .Replace("-", string.Empty)
+ .ToLower(CultureInfo.CurrentCulture);
+#endif
}
///
@@ -520,7 +616,8 @@ public static class StringExtensions
///
public static string Sub(this string me, int startIndex, int length)
{
- if (startIndex + length > me.Length) {
+ if (startIndex + length > me.Length)
+ {
length = me.Length - startIndex;
}
@@ -540,10 +637,7 @@ public static class StringExtensions
///
public static string ToLowerCamelCase(this string me)
{
- return string.IsNullOrWhiteSpace(me)
- ? me
- : string.Concat( //
- me[0].ToString(CultureInfo.InvariantCulture).ToLowerInvariant(), me.AsSpan(1));
+ return string.IsNullOrWhiteSpace(me) ? me : string.Concat(me[0].ToString(CultureInfo.InvariantCulture).ToLowerInvariant(), me.AsSpan(1));
}
///
@@ -554,6 +648,14 @@ public static class StringExtensions
return string.IsNullOrWhiteSpace(me) ? me : string.Concat(me[0].ToString().ToUpperInvariant(), me.AsSpan(1));
}
+ ///
+ /// 去掉前部字符串
+ ///
+ public static string TrimPrefix(this string me, string clearStr)
+ {
+ return Regex.Replace(me, $"^{clearStr}", string.Empty);
+ }
+
///
/// 将连续多个空格替换成一个空格
///
@@ -565,24 +667,25 @@ public static class StringExtensions
return ret == me ? ret : ret.TrimSpaces();
}
+ ///
+ /// 去掉尾部字符串
+ ///
+ public static string TrimSuffix(this string me, string clearStr)
+ {
+ return Regex.Replace(me, $"{clearStr}$", string.Empty);
+ }
+
///
/// 将\ux0000 、 %u0000 、 � 编码转换成可读字符串
///
public static string UnicodeDe(this string me)
{
+#pragma warning disable S3358, RCS1238
const string replacement = "$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();
+ return !me.Contains(@"\u")
+ ? me.Contains("%u") ? Regexes.RegexPercentUnicode.Replace(me, replacement).HtmlDe() : me.HtmlDe()
+ : Regexes.RegexBacksLantUnicode.Replace(me, replacement).HtmlDe();
+#pragma warning restore S3358, RCS1238
}
///
@@ -614,16 +717,15 @@ public static class StringExtensions
/// hash摘要的16进制文本形式(无连字符小写)
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
+
+#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
+#else
+ return BitConverter.ToString(md5Hmac.ComputeHash(e.GetBytes(me))).Replace("-", string.Empty).ToLower(CultureInfo.CurrentCulture);
+#endif
}
-}
-#pragma warning restore CodeLinesAnalyzer
\ No newline at end of file
+
+ [GeneratedRegex(@"^(25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})){3}$")]
+ private static partial Regex RegexIpV4();
+}
\ No newline at end of file
diff --git a/src/backend/NSExt/NSExt.csproj b/src/backend/NSExt/NSExt.csproj
index 5969fdd..0d9a425 100644
--- a/src/backend/NSExt/NSExt.csproj
+++ b/src/backend/NSExt/NSExt.csproj
@@ -7,7 +7,9 @@
+
+