using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Numerics;
using System.Text;
namespace Masuit.Tools.Strings;
///
/// 数制格式化器
///
public class UnicodeFormater
{
///
/// 数制表示字符集
///
private List Characters { get; }
///
/// 进制长度
///
public int Length => Characters.Count;
///
/// 起始值偏移
///
private readonly byte _offset;
///
/// 数制格式化器
///
public UnicodeFormater()
{
Characters = new List() { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
}
///
/// 数制格式化器
///
/// 符号集
/// 起始值偏移
public UnicodeFormater(string characters, byte offset = 0)
{
if (string.IsNullOrEmpty(characters))
{
throw new ArgumentException("符号集不能为空");
}
var enumerator = StringInfo.GetTextElementEnumerator(characters);
Characters = new List();
while (enumerator.MoveNext())
{
Characters.Add(enumerator.GetTextElement());
}
_offset = offset;
}
///
/// 数制格式化器
///
/// 符号集
/// 起始值偏移
public UnicodeFormater(List characters, byte offset = 0)
{
if (characters.IsNullOrEmpty())
{
throw new ArgumentException("符号集不能为空");
}
Characters = characters;
_offset = offset;
}
#if NET5_0_OR_GREATER
///
/// 数制格式化器
///
/// 符号集
/// 起始值偏移
public UnicodeFormater(ReadOnlySpan 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;
}
///
/// 数制格式化器
///
/// 符号集
/// 起始值偏移
public UnicodeFormater(ReadOnlySpan characters, byte offset = 0)
{
if (characters == null || characters.Length == 0)
{
throw new ArgumentException("符号集不能为空");
}
Characters = characters.ToString().Select(c => c.ToString()).ToList();
_offset = offset;
}
#endif
///
/// 数制格式化器
///
/// 符号集
/// 起始值偏移
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;
}
///
/// 数制格式化器
///
/// 符号集
/// 起始值偏移
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;
}
///
/// 数制格式化器
///
/// 进制
/// 起始值偏移
public UnicodeFormater(byte @base, byte offset = 0)
{
Characters = @base switch
{
<= 2 => new List() { "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;
}
///
/// 数字转换为指定的进制形式字符串
///
///
///
public string ToString(long number)
{
int start = 0;
int resultOffset = 0;
if (_offset > 0)
{
start = 1;
resultOffset = _offset - 1;
}
number -= resultOffset;
List result = [];
long t = Math.Abs(number);
while (t != 0)
{
var mod = t % Length;
t = Math.Abs(t / Length);
var character = Characters[Convert.ToInt32(mod) - start];
result.Insert(0, character);
}
if (number < 0)
{
result.Insert(0, "-");
}
return string.Join("", result);
}
///
/// 数字转换为指定的进制形式字符串
///
///
///
public string ToString(BigInteger number)
{
int start = 0;
int resultOffset = 0;
if (_offset > 0)
{
start = 1;
resultOffset = _offset - 1;
}
number -= resultOffset;
List result = [];
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];
result.Insert(0, character);
}
return string.Join("", result);
}
///
/// 指定字符串转换为指定进制的数字形式
///
///
///
public long FromString(string str)
{
byte start = 0;
int resultOffset = 0;
if (_offset > 0)
{
start = 1;
resultOffset = _offset - 1;
}
int j = 0;
var emoji = new List();
var enumerator = StringInfo.GetTextElementEnumerator(str);
while (enumerator.MoveNext())
{
emoji.Add(enumerator.GetTextElement());
}
emoji.Reverse();
return emoji.Where(Characters.Contains).Sum(ch => (Characters.IndexOf(ch) + start) * (long)Math.Pow(Length, j++)) + resultOffset;
}
///
/// 指定字符串转换为指定进制的大数形式
///
///
///
public BigInteger FromStringBig(string str)
{
byte start = 0;
int resultOffset = 0;
if (_offset > 0)
{
start = 1;
resultOffset = _offset - 1;
}
int j = 0;
var emoji = new List();
var enumerator = StringInfo.GetTextElementEnumerator(str);
while (enumerator.MoveNext())
{
emoji.Add(enumerator.GetTextElement());
}
emoji.Reverse();
return emoji.Where(Characters.Contains).Aggregate(BigInteger.Zero, (current, c) => current + (Characters.IndexOf(c) + start) * BigInteger.Pow(Length, j++)) + resultOffset;
}
/// Returns a string that represents the current object.
/// A string that represents the current object.
public override string ToString()
{
return Length + "进制模式,进制符:" + Characters.Join("");
}
}