using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
namespace Masuit.Tools.Excel
{
///
/// 数制格式化器
///
internal class NumberFormater
{
///
/// 数制表示字符集
///
internal string Characters { get; set; }
///
/// 进制长度
///
public int Length => Characters.Length;
///
/// 起始值偏移
///
private readonly int _offset;
///
/// 数制格式化器
///
public NumberFormater()
{
Characters = "0123456789";
}
///
/// 数制格式化器
///
/// 符号集
/// 起始值偏移
public NumberFormater(string characters, int offset = 0)
{
if (string.IsNullOrEmpty(characters))
{
throw new ArgumentException("符号集不能为空");
}
Characters = characters;
_offset = offset;
}
///
/// 数制格式化器
///
/// 进制
/// 起始值偏移
public NumberFormater(int bin, int offset = 0)
{
if (bin < 2)
{
bin = 2;
}
if (bin > 64)
{
throw new ArgumentException("默认进制最大支持64进制");
}
Characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/".Substring(0, bin);
_offset = offset;
}
///
/// 数字转换为指定的进制形式字符串
///
///
///
public string ToString(long number)
{
List result = new List();
long t = Math.Abs(number);
while (t != 0)
{
var mod = t % Length;
t = Math.Abs(t / Length);
var character = Characters[Convert.ToInt32(mod) - _offset].ToString();
result.Insert(0, character);
}
if (number < 0)
{
result.Insert(0, "-");
}
return string.Join("", result);
}
///
/// 数字转换为指定的进制形式字符串
///
///
///
public string ToString(BigInteger number)
{
List result = new List();
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 - _offset].ToString();
result.Insert(0, character);
}
return string.Join("", result);
}
///
/// 指定字符串转换为指定进制的数字形式
///
///
///
public long FromString(string str)
{
int j = 0;
return new string(str.ToCharArray().Reverse().ToArray()).Where(ch => Characters.Contains(ch)).Sum(ch => (Characters.IndexOf(ch) + _offset) * (long)Math.Pow(Length, j++));
}
///
/// 指定字符串转换为指定进制的大数形式
///
///
///
public BigInteger FromStringBig(string str)
{
int j = 0;
var chars = new string(str.ToCharArray().Reverse().ToArray()).Where(ch => Characters.Contains(ch));
return chars.Aggregate(BigInteger.Zero, (current, c) => current + (Characters.IndexOf(c) + _offset) * BigInteger.Pow(Length, j++));
}
/// Returns a string that represents the current object.
/// A string that represents the current object.
public override string ToString()
{
return Length + "进制模式,进制符:" + Characters;
}
}
}