NumberFormater.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Numerics;
  5. namespace Masuit.Tools.Excel
  6. {
  7. /// <summary>
  8. /// 数制格式化器
  9. /// </summary>
  10. internal class NumberFormater
  11. {
  12. /// <summary>
  13. /// 数制表示字符集
  14. /// </summary>
  15. internal string Characters { get; set; }
  16. /// <summary>
  17. /// 进制长度
  18. /// </summary>
  19. public int Length => Characters.Length;
  20. /// <summary>
  21. /// 起始值偏移
  22. /// </summary>
  23. private readonly int _offset;
  24. /// <summary>
  25. /// 数制格式化器
  26. /// </summary>
  27. public NumberFormater()
  28. {
  29. Characters = "0123456789";
  30. }
  31. /// <summary>
  32. /// 数制格式化器
  33. /// </summary>
  34. /// <param name="characters">符号集</param>
  35. /// <param name="offset">起始值偏移</param>
  36. public NumberFormater(string characters, int offset = 0)
  37. {
  38. if (string.IsNullOrEmpty(characters))
  39. {
  40. throw new ArgumentException("符号集不能为空");
  41. }
  42. Characters = characters;
  43. _offset = offset;
  44. }
  45. /// <summary>
  46. /// 数制格式化器
  47. /// </summary>
  48. /// <param name="bin">进制</param>
  49. /// <param name="offset">起始值偏移</param>
  50. public NumberFormater(int bin, int offset = 0)
  51. {
  52. if (bin < 2)
  53. {
  54. bin = 2;
  55. }
  56. if (bin > 64)
  57. {
  58. throw new ArgumentException("默认进制最大支持64进制");
  59. }
  60. Characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/".Substring(0, bin);
  61. _offset = offset;
  62. }
  63. /// <summary>
  64. /// 数字转换为指定的进制形式字符串
  65. /// </summary>
  66. /// <param name="number"></param>
  67. /// <returns></returns>
  68. public string ToString(long number)
  69. {
  70. List<string> result = new List<string>();
  71. long t = Math.Abs(number);
  72. while (t != 0)
  73. {
  74. var mod = t % Length;
  75. t = Math.Abs(t / Length);
  76. var character = Characters[Convert.ToInt32(mod) - _offset].ToString();
  77. result.Insert(0, character);
  78. }
  79. if (number < 0)
  80. {
  81. result.Insert(0, "-");
  82. }
  83. return string.Join("", result);
  84. }
  85. /// <summary>
  86. /// 数字转换为指定的进制形式字符串
  87. /// </summary>
  88. /// <param name="number"></param>
  89. /// <returns></returns>
  90. public string ToString(BigInteger number)
  91. {
  92. List<string> result = new List<string>();
  93. if (number < 0)
  94. {
  95. number = -number;
  96. result.Add("0");
  97. }
  98. BigInteger t = number;
  99. while (t != 0)
  100. {
  101. var mod = t % Length;
  102. t = BigInteger.Abs(BigInteger.Divide(t, Length));
  103. var character = Characters[(int)mod - _offset].ToString();
  104. result.Insert(0, character);
  105. }
  106. return string.Join("", result);
  107. }
  108. /// <summary>
  109. /// 指定字符串转换为指定进制的数字形式
  110. /// </summary>
  111. /// <param name="str"></param>
  112. /// <returns></returns>
  113. public long FromString(string str)
  114. {
  115. int j = 0;
  116. return new string(str.ToCharArray().Reverse().ToArray()).Where(ch => Characters.Contains(ch)).Sum(ch => (Characters.IndexOf(ch) + _offset) * (long)Math.Pow(Length, j++));
  117. }
  118. /// <summary>
  119. /// 指定字符串转换为指定进制的大数形式
  120. /// </summary>
  121. /// <param name="str"></param>
  122. /// <returns></returns>
  123. public BigInteger FromStringBig(string str)
  124. {
  125. int j = 0;
  126. var chars = new string(str.ToCharArray().Reverse().ToArray()).Where(ch => Characters.Contains(ch));
  127. return chars.Aggregate(BigInteger.Zero, (current, c) => current + (Characters.IndexOf(c) + _offset) * BigInteger.Pow(Length, j++));
  128. }
  129. /// <summary>Returns a string that represents the current object.</summary>
  130. /// <returns>A string that represents the current object.</returns>
  131. public override string ToString()
  132. {
  133. return Length + "进制模式,进制符:" + Characters;
  134. }
  135. }
  136. }