2023-10-20 19:37:19 -07:00

64 lines
1.9 KiB
C#

namespace BlurHash;
/// <summary>
/// Contains methods to encode or decode integers to Base83-Strings
/// </summary>
internal static class Base83
{
internal const string _Charset = @"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~";
private static readonly IReadOnlyDictionary<char, int> _ReverseLookup;
static Base83()
{
// Build inverse lookup table for fast decoding
Dictionary<char, int> charIndices = [];
int index = 0;
foreach (char c in _Charset)
{
charIndices[c] = index;
index++;
}
_ReverseLookup = charIndices;
}
/// <summary>
/// Encodes a number into its Base83-representation
/// </summary>
/// <param name="number">The number to encode</param>
/// <param name="output">The data buffer to put the result data into</param>
/// <returns>The Base83-representation of the number</returns>
public static void EncodeBase83(this int number, Span<char> output)
{
int length = output.Length;
for (int i = 0; i < length; i++)
{
int digit = number % 83;
number /= 83;
output[length - i - 1] = _Charset[digit];
}
}
/// <summary>
/// Decodes an <code>IEnumerable</code> of Base83-characters into the integral value it represents
/// </summary>
/// <param name="base83Data">The characters to decode</param>
/// <returns>The decoded value as integer</returns>
public static int DecodeBase83(this ReadOnlySpan<char> base83Data)
{
int result = 0;
foreach (char c in base83Data)
{
if (!_ReverseLookup.TryGetValue(c, out int digit))
{
throw new ArgumentException("The given string contains invalid characters.", nameof(base83Data));
}
result *= 83;
result += digit;
}
return result;
}
}