Browse Source

NumberFormater支持91进制

懒得勤快 2 years ago
parent
commit
2e85cce901

+ 10 - 0
Masuit.Tools.Abstractions/Extensions/BaseType/StringExtensions.cs

@@ -807,5 +807,15 @@ $", RegexOptions.IgnorePatternWhitespace | RegexOptions.IgnoreCase | RegexOption
         /// <param name="that"></param>
         /// <returns></returns>
         public static int HammingDistance(this string @this, string that) => new SimHash(@this).HammingDistance(new SimHash(that));
+
+        /// <summary>
+        /// 匹配字符串是否包含emoji字符
+        /// </summary>
+        /// <param name="s"></param>
+        /// <returns></returns>
+        public static bool MatchEmoji(this string s)
+        {
+            return Regex.IsMatch(s, @"(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])");
+        }
     }
 }

+ 75 - 9
Masuit.Tools.Abstractions/Strings/NumberFormater.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Globalization;
 using System.Linq;
 using System.Numerics;
+using System.Text;
 using System.Text.RegularExpressions;
 
 namespace Masuit.Tools.Strings
@@ -15,7 +16,7 @@ namespace Masuit.Tools.Strings
         /// <summary>
         /// 数制表示字符集
         /// </summary>
-        private string Characters { get; set; }
+        private string Characters { get; }
 
         /// <summary>
         /// 进制长度
@@ -51,24 +52,89 @@ namespace Masuit.Tools.Strings
             _offset = offset;
         }
 
+#if NET5_0_OR_GREATER
+
         /// <summary>
         /// 数制格式化器
         /// </summary>
-        /// <param name="base">进制</param>
+        /// <param name="characters">符号集</param>
         /// <param name="offset">起始值偏移</param>
-        public NumberFormater(byte @base, byte offset = 0)
+        public NumberFormater(ReadOnlySpan<byte> characters, byte offset = 0)
         {
-            if (@base < 2)
+            if (characters == null || characters.Length == 0)
             {
-                @base = 2;
+                throw new ArgumentException("符号集不能为空");
             }
 
-            if (@base > 64)
+            Characters = Encoding.UTF8.GetString(characters);
+            _offset = offset;
+        }
+
+        /// <summary>
+        /// 数制格式化器
+        /// </summary>
+        /// <param name="characters">符号集</param>
+        /// <param name="offset">起始值偏移</param>
+        public NumberFormater(ReadOnlySpan<char> characters, byte offset = 0)
+        {
+            if (characters == null || characters.Length == 0)
             {
-                throw new ArgumentException("默认进制最大支持64进制");
+                throw new ArgumentException("符号集不能为空");
             }
 
-            Characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/".Substring(0, @base);
+            Characters = new string(characters);
+            _offset = offset;
+        }
+
+#endif
+
+        /// <summary>
+        /// 数制格式化器
+        /// </summary>
+        /// <param name="characters">符号集</param>
+        /// <param name="offset">起始值偏移</param>
+        public NumberFormater(byte[] characters, byte offset = 0)
+        {
+            if (characters == null || characters.Length == 0)
+            {
+                throw new ArgumentException("符号集不能为空");
+            }
+
+            Characters = Encoding.UTF8.GetString(characters);
+            _offset = offset;
+        }
+
+        /// <summary>
+        /// 数制格式化器
+        /// </summary>
+        /// <param name="characters">符号集</param>
+        /// <param name="offset">起始值偏移</param>
+        public NumberFormater(char[] characters, byte offset = 0)
+        {
+            if (characters == null || characters.Length == 0)
+            {
+                throw new ArgumentException("符号集不能为空");
+            }
+
+            Characters = new string(characters);
+            _offset = offset;
+        }
+
+        /// <summary>
+        /// 数制格式化器
+        /// </summary>
+        /// <param name="base">进制</param>
+        /// <param name="offset">起始值偏移</param>
+        public NumberFormater(byte @base, byte offset = 0)
+        {
+            Characters = @base switch
+            {
+                <= 2 => "01",
+                > 2 and < 65 => "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/".Substring(0, @base),
+                >= 65 and <= 91 => "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,-.:;<=>?@[]^_`{|}~\"".Substring(0, @base),
+                _ => throw new ArgumentException("默认进制最大支持91进制")
+            };
+
             if (offset >= @base)
             {
                 throw new ArgumentException("偏移量不能超过进制基数" + @base);
@@ -92,7 +158,7 @@ namespace Masuit.Tools.Strings
                 resultOffset = _offset - 1;
             }
 
-            number = number - resultOffset;
+            number -= resultOffset;
             List<string> result = new List<string>();
             long t = Math.Abs(number);
             while (t != 0)

+ 293 - 0
Masuit.Tools.Abstractions/Strings/UnicodeFormater.cs

@@ -0,0 +1,293 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Numerics;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace Masuit.Tools.Strings
+{
+    /// <summary>
+    /// 数制格式化器
+    /// </summary>
+    public class UnicodeFormater
+    {
+        /// <summary>
+        /// 数制表示字符集
+        /// </summary>
+        private List<string> Characters { get; }
+
+        /// <summary>
+        /// 进制长度
+        /// </summary>
+        public int Length => Characters.Count;
+
+        /// <summary>
+        /// 起始值偏移
+        /// </summary>
+        private readonly byte _offset;
+
+        /// <summary>
+        /// 数制格式化器
+        /// </summary>
+        public UnicodeFormater()
+        {
+            Characters = new List<string>() { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
+        }
+
+        /// <summary>
+        /// 数制格式化器
+        /// </summary>
+        /// <param name="characters">符号集</param>
+        /// <param name="offset">起始值偏移</param>
+        public UnicodeFormater(string characters, byte offset = 0)
+        {
+            if (string.IsNullOrEmpty(characters))
+            {
+                throw new ArgumentException("符号集不能为空");
+            }
+
+            var matches = Regex.Matches(characters, @"(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])");
+            if (matches.Count > 0)
+            {
+                Characters = new List<string>();
+                foreach (Match m in matches)
+                {
+                    Characters.Add(m.Value);
+                }
+            }
+            else
+            {
+                Characters = characters.Select(c => c.ToString()).ToList();
+            }
+
+            _offset = offset;
+        }
+
+        /// <summary>
+        /// 数制格式化器
+        /// </summary>
+        /// <param name="characters">符号集</param>
+        /// <param name="offset">起始值偏移</param>
+        public UnicodeFormater(List<string> characters, byte offset = 0)
+        {
+            if (characters.IsNullOrEmpty())
+            {
+                throw new ArgumentException("符号集不能为空");
+            }
+
+            Characters = characters;
+            _offset = offset;
+        }
+
+#if NET5_0_OR_GREATER
+
+        /// <summary>
+        /// 数制格式化器
+        /// </summary>
+        /// <param name="characters">符号集</param>
+        /// <param name="offset">起始值偏移</param>
+        public UnicodeFormater(ReadOnlySpan<byte> characters, byte offset = 0)
+        {
+            if (characters == null || characters.Length == 0)
+            {
+                throw new ArgumentException("符号集不能为空");
+            }
+
+            Characters = Encoding.UTF8.GetString(characters).Select(c => c.ToString()).ToList();
+            _offset = offset;
+        }
+
+        /// <summary>
+        /// 数制格式化器
+        /// </summary>
+        /// <param name="characters">符号集</param>
+        /// <param name="offset">起始值偏移</param>
+        public UnicodeFormater(ReadOnlySpan<char> characters, byte offset = 0)
+        {
+            if (characters == null || characters.Length == 0)
+            {
+                throw new ArgumentException("符号集不能为空");
+            }
+
+            Characters = new string(characters).Select(c => c.ToString()).ToList();;
+            _offset = offset;
+        }
+
+#endif
+
+        /// <summary>
+        /// 数制格式化器
+        /// </summary>
+        /// <param name="characters">符号集</param>
+        /// <param name="offset">起始值偏移</param>
+        public UnicodeFormater(byte[] characters, byte offset = 0)
+        {
+            if (characters == null || characters.Length == 0)
+            {
+                throw new ArgumentException("符号集不能为空");
+            }
+
+            Characters = Encoding.UTF8.GetString(characters).Select(c => c.ToString()).ToList(); ;
+            _offset = offset;
+        }
+
+        /// <summary>
+        /// 数制格式化器
+        /// </summary>
+        /// <param name="characters">符号集</param>
+        /// <param name="offset">起始值偏移</param>
+        public UnicodeFormater(char[] characters, byte offset = 0)
+        {
+            if (characters == null || characters.Length == 0)
+            {
+                throw new ArgumentException("符号集不能为空");
+            }
+
+            Characters = characters.Select(c => c.ToString()).ToList(); ;
+            _offset = offset;
+        }
+
+        /// <summary>
+        /// 数制格式化器
+        /// </summary>
+        /// <param name="base">进制</param>
+        /// <param name="offset">起始值偏移</param>
+        public UnicodeFormater(byte @base, byte offset = 0)
+        {
+            Characters = @base switch
+            {
+                <= 2 => new List<string>() { "0", "1" },
+                > 2 and < 65 => "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/".Substring(0, @base).Select(c => c.ToString()).ToList(),
+                >= 65 and <= 91 => "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,-.:;<=>?@[]^_`{|}~\"".Substring(0, @base).Select(c => c.ToString()).ToList(),
+                _ => throw new ArgumentException("默认进制最大支持91进制")
+            };
+
+            if (offset >= @base)
+            {
+                throw new ArgumentException("偏移量不能超过进制基数" + @base);
+            }
+
+            _offset = offset;
+        }
+
+        /// <summary>
+        /// 数字转换为指定的进制形式字符串
+        /// </summary>
+        /// <param name="number"></param>
+        /// <returns></returns>
+        public string ToString(long number)
+        {
+            int start = 0;
+            int resultOffset = 0;
+            if (_offset > 0)
+            {
+                start = 1;
+                resultOffset = _offset - 1;
+            }
+
+            number -= resultOffset;
+            List<string> result = new List<string>();
+            long t = Math.Abs(number);
+            while (t != 0)
+            {
+                var mod = t % Length;
+                t = Math.Abs(t / Length);
+                var character = Characters[Convert.ToInt32(mod) - start].ToString();
+                result.Insert(0, character);
+            }
+
+            if (number < 0)
+            {
+                result.Insert(0, "-");
+            }
+
+            return string.Join("", result);
+        }
+
+        /// <summary>
+        /// 数字转换为指定的进制形式字符串
+        /// </summary>
+        /// <param name="number"></param>
+        /// <returns></returns>
+        public string ToString(BigInteger number)
+        {
+            int start = 0;
+            int resultOffset = 0;
+            if (_offset > 0)
+            {
+                start = 1;
+                resultOffset = _offset - 1;
+            }
+
+            number = number - resultOffset;
+            List<string> result = new List<string>();
+            if (number < 0)
+            {
+                number = -number;
+                result.Add("0");
+            }
+
+            BigInteger t = number;
+
+            while (t != 0)
+            {
+                var mod = t % Length;
+                t = BigInteger.Abs(BigInteger.Divide(t, Length));
+                var character = Characters[(int)mod - start].ToString();
+                result.Insert(0, character);
+            }
+
+            return string.Join("", result);
+        }
+
+        /// <summary>
+        /// 指定字符串转换为指定进制的数字形式
+        /// </summary>
+        /// <param name="str"></param>
+        /// <returns></returns>
+        public long FromString(string str)
+        {
+            byte start = 0;
+            int resultOffset = 0;
+            if (_offset > 0)
+            {
+                start = 1;
+                resultOffset = _offset - 1;
+            }
+
+            int j = 0;
+            var chars = str.ToCharArray();
+            Array.Reverse(chars);
+            return new string(chars).Where(c => Characters.Contains(c.ToString())).Sum(ch => (Characters.IndexOf(ch.ToString()) + start) * (long)Math.Pow(Length, j++)) + resultOffset;
+        }
+
+        /// <summary>
+        /// 指定字符串转换为指定进制的大数形式
+        /// </summary>
+        /// <param name="str"></param>
+        /// <returns></returns>
+        public BigInteger FromStringBig(string str)
+        {
+            byte start = 0;
+            int resultOffset = 0;
+            if (_offset > 0)
+            {
+                start = 1;
+                resultOffset = _offset - 1;
+            }
+            int j = 0;
+            var charArray = str.ToCharArray();
+            Array.Reverse(charArray);
+            var chars = charArray.Where(c => Characters.Contains(c.ToString()));
+            return chars.Aggregate(BigInteger.Zero, (current, c) => current + (Characters.IndexOf(c.ToString()) + start) * BigInteger.Pow(Length, j++)) + resultOffset;
+        }
+
+        /// <summary>Returns a string that represents the current object.</summary>
+        /// <returns>A string that represents the current object.</returns>
+        public override string ToString()
+        {
+            return Length + "进制模式,进制符:" + Characters.Join("");
+        }
+    }
+}

+ 3 - 0
Masuit.Tools.Net45/Masuit.Tools.Net45.csproj

@@ -196,6 +196,9 @@
     <Compile Include="..\Masuit.Tools.Abstractions\Strings\Template.cs">
       <Link>Strings\Template.cs</Link>
     </Compile>
+    <Compile Include="..\Masuit.Tools.Abstractions\Strings\UnicodeFormater.cs">
+      <Link>Strings\UnicodeFormater.cs</Link>
+    </Compile>
     <Compile Include="..\Masuit.Tools.Abstractions\Systems\*.*">
       <Link>Systems\%(RecursiveDir)%(FileName)%(Extension)</Link>
     </Compile>

+ 3 - 0
Masuit.Tools/Masuit.Tools.csproj

@@ -118,6 +118,9 @@
     <Compile Include="..\Masuit.Tools.Abstractions\Strings\Template.cs">
       <Link>Strings\Template.cs</Link>
     </Compile>
+    <Compile Include="..\Masuit.Tools.Abstractions\Strings\UnicodeFormater.cs">
+      <Link>Strings\UnicodeFormater.cs</Link>
+    </Compile>
     <Compile Include="..\Masuit.Tools.Abstractions\Systems\*.*">
       <Link>Systems\%(RecursiveDir)%(FileName)%(Extension)</Link>
     </Compile>