Base32 conversions

This commit is contained in:
2024-09-08 18:37:38 +02:00
parent 0fc24b8307
commit d4ef0dc34e
3 changed files with 130 additions and 2 deletions
@@ -0,0 +1,128 @@
namespace System.Extensions;
/// <summary>
/// https://stackoverflow.com/questions/641361/base32-decoding
/// </summary>
public static partial class Convert
{
public static byte[] FromBase32String(string input)
{
if (string.IsNullOrEmpty(input))
{
throw new ArgumentNullException("input");
}
input = input.TrimEnd('='); //remove padding characters
var byteCount = input.Length * 5 / 8; //this must be TRUNCATED
var returnArray = new byte[byteCount];
byte curByte = 0, bitsRemaining = 8;
int arrayIndex = 0;
foreach (var c in input)
{
var cValue = CharToValue(c);
int mask;
if (bitsRemaining > 5)
{
mask = cValue << (bitsRemaining - 5);
curByte = (byte)(curByte | mask);
bitsRemaining -= 5;
}
else
{
mask = cValue >> (5 - bitsRemaining);
curByte = (byte)(curByte | mask);
returnArray[arrayIndex++] = curByte;
curByte = (byte)(cValue << (3 + bitsRemaining));
bitsRemaining += 3;
}
}
//if we didn't end with a full byte
if (arrayIndex != byteCount)
{
returnArray[arrayIndex] = curByte;
}
return returnArray;
}
public static string ToBase32String(byte[] input)
{
if (input == null || input.Length == 0)
{
throw new ArgumentNullException("input");
}
var charCount = (int)Math.Ceiling(input.Length / 5d) * 8;
var returnArray = new char[charCount];
byte nextChar = 0, bitsRemaining = 5;
var arrayIndex = 0;
foreach (var b in input)
{
nextChar = (byte)(nextChar | (b >> (8 - bitsRemaining)));
returnArray[arrayIndex++] = ValueToChar(nextChar);
if (bitsRemaining < 4)
{
nextChar = (byte)((b >> (3 - bitsRemaining)) & 31);
returnArray[arrayIndex++] = ValueToChar(nextChar);
bitsRemaining += 5;
}
bitsRemaining -= 3;
nextChar = (byte)((b << bitsRemaining) & 31);
}
//if we didn't end with a full char
if (arrayIndex != charCount)
{
returnArray[arrayIndex++] = ValueToChar(nextChar);
while (arrayIndex != charCount) returnArray[arrayIndex++] = '='; //padding
}
return new string(returnArray);
}
private static int CharToValue(char c)
{
var value = (int)c;
//65-90 == uppercase letters
if (value < 91 && value > 64)
{
return value - 65;
}
//50-55 == numbers 2-7
if (value < 56 && value > 49)
{
return value - 24;
}
//97-122 == lowercase letters
if (value < 123 && value > 96)
{
return value - 97;
}
throw new ArgumentException($"Character {c} is not a Base32 character.");
}
private static char ValueToChar(byte b)
{
if (b < 26)
{
return (char)(b + 65);
}
if (b < 32)
{
return (char)(b + 24);
}
throw new ArgumentException($"Byte {b} is not a value Base32 value.");
}
}
@@ -7,7 +7,7 @@
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<RootNamespace>System</RootNamespace>
<Version>1.6.7</Version>
<Version>1.6.8</Version>
<Authors>Alexandru Macocian</Authors>
<RepositoryUrl>https://github.com/AlexMacocian/SystemExtensions</RepositoryUrl>
<Description>Extensions for the System namespace</Description>