AP.NET/Utils/Base36.cs

56 lines
1.8 KiB
C#

namespace ActivityPub.Utils;
/// <summary>
/// Helper class for converting numbers to and from Base36 strings
/// https://stackoverflow.com/a/35004409
/// </summary>
public class Base36
{
private static readonly char[] BaseChars =
"0123456789abcdefghijklmnopqrstuvwxyz".ToCharArray();
private static readonly Dictionary<char, int> CharValues = BaseChars
.Select((c, i) => new { Char = c, Index = i })
.ToDictionary(c => c.Char, c => c.Index);
/// <summary>
/// Convert a long to a Base36 string
/// </summary>
/// <param name="value">The number to convert</param>
/// <returns>A string representing the number in Base36</returns>
public static string ToString(long value)
{
long targetBase = BaseChars.Length;
// Determine exact number of characters to use.
char[] buffer = new char[Math.Max(
(int)Math.Ceiling(Math.Log(value + 1, targetBase)), 1)];
var i = buffer.Length;
do
{
buffer[--i] = BaseChars[value % targetBase];
value = value / targetBase;
}
while (value > 0);
return new string(buffer, i, buffer.Length - i);
}
/// <summary>
/// Converts a Base64 string back into a number
/// </summary>
/// <param name="number">The string to convert</param>
/// <returns>The number resulting from converting the string</returns>
public static long FromString(string number)
{
char[] chrs = number.ToLower().ToCharArray();
int m = chrs.Length - 1;
int n = BaseChars.Length, x;
long result = 0;
for (int i = 0; i < chrs.Length; i++)
{
x = CharValues[chrs[i]];
result += x * (long)Math.Pow(n, m--);
}
return result;
}
}