Skip to content

Instantly share code, notes, and snippets.

@heathbm
Last active December 7, 2022 07:51
Show Gist options
  • Select an option

  • Save heathbm/f59662bd2334761d28288755a34e29ec to your computer and use it in GitHub Desktop.

Select an option

Save heathbm/f59662bd2334761d28288755a34e29ec to your computer and use it in GitHub Desktop.
The `Base64` decoding methods should handle whitespace chars as the `Convert.ToBase64` decoding methods. This should test 100,000s of unique base64 strings with white space chars inserted into every possible index, and multiple indexes at once, in strings ranging from 1 to 70 chars long.
using System.Buffers;
using System.Buffers.Text;
using System.Text;
public static class Base64DecodingTests
{
public static void Testing()
{
ReadOnlySpan<char> text = "abcdefghijklmnopqrstuvxyz0123456789abcdefghijklmnopqrstuvxyz0123456789".AsSpan();
Console.WriteLine("In Place: ");
for (int i = 1; i < text.Length; i++)
{
for (int j = 0; j < 20; j++)
{
Test(text.Slice(0, i), j, 0, true);
Test(text.Slice(0, i), j, 1, true);
Test(text.Slice(0, i), j, 2, true);
Test(text.Slice(0, i), j, 3, true);
Test(text.Slice(0, i), j, 4, true);
Test(text.Slice(0, i), j, 5, true);
}
}
Console.WriteLine($"Pass: {totalGood}");
Console.WriteLine($"Fail: {totalFail}");
totalGood = 0;
totalFail = 0;
Console.WriteLine("\nNormal: ");
for (int i = 1; i < text.Length; i++)
{
for (int j = 0; j < 20; j++)
{
Test(text.Slice(0, i), j, 0, false);
Test(text.Slice(0, i), j, 1, false);
Test(text.Slice(0, i), j, 2, false);
Test(text.Slice(0, i), j, 3, false);
Test(text.Slice(0, i), j, 4, false);
Test(text.Slice(0, i), j, 5, false);
}
}
Console.WriteLine($"Pass: {totalGood}");
Console.WriteLine($"Fail: {totalFail}");
}
static int totalFail = 0;
static int totalGood = 0;
private static void Test(ReadOnlySpan<char> text, int instances, int typeOfTest, bool inPlace)
{
try
{
byte[] utf8Bytes = Encoding.UTF8.GetBytes(text.ToString());
string base64Utf8String = Convert.ToBase64String(utf8Bytes);
string backup = base64Utf8String;
for (int i = 0; i < backup.Length; i++)
{
var firstSegment = backup.Substring(0, i);
var secondSegment = backup.Substring(i, backup.Length - i);
if (typeOfTest == 0)
{
base64Utf8String = $"{firstSegment}{new string(Convert.ToChar(10), instances)}{secondSegment}";
}
if (typeOfTest == 1)
{
base64Utf8String = $"{new string(Convert.ToChar(10), instances)}{firstSegment}{secondSegment}";
}
if (typeOfTest == 2)
{
base64Utf8String = $"{firstSegment}{secondSegment}{new string(Convert.ToChar(10), instances)}";
}
if (typeOfTest == 3)
{
base64Utf8String = $"{firstSegment}{new string(Convert.ToChar(10), instances)}{secondSegment}{new string(Convert.ToChar(10), instances)}";
}
if (typeOfTest == 4)
{
base64Utf8String = $"{new string(Convert.ToChar(10), instances)}{firstSegment}{new string(Convert.ToChar(10), instances)}{secondSegment}{new string(Convert.ToChar(10), instances)}";
}
if (typeOfTest == 5)
{
base64Utf8String = $"{new string(Convert.ToChar(10), instances)}{firstSegment}{new string(Convert.ToChar(10), instances)}{secondSegment}";
}
if (typeOfTest == 6)
{
base64Utf8String = $"{firstSegment}{secondSegment}";
}
var bytesFromConvert = Convert.FromBase64String(base64Utf8String);
string base64Utf8StringFromConvert = Convert.ToBase64String(utf8Bytes);
var resultStringFromConvert = Encoding.UTF8.GetString(bytesFromConvert);
ReadOnlySpan<byte> utf8BytesWithByteToBeIgnored = UTF8Encoding.UTF8.GetBytes(base64Utf8String);
OperationStatus resultEnum;
Span<byte> resultBytesForDecode = new byte[150];
int bytesWritten;
int bytesConsumed;
if (inPlace)
{
resultBytesForDecode = utf8BytesWithByteToBeIgnored.ToArray().AsSpan();
resultEnum = Base64.DecodeFromUtf8InPlace(resultBytesForDecode, out bytesWritten);
}
else
{
resultEnum = Base64.DecodeFromUtf8(utf8BytesWithByteToBeIgnored, resultBytesForDecode, out bytesConsumed, out bytesWritten);
}
string base64StringFromDecode = Convert.ToBase64String(resultBytesForDecode).Substring(0, bytesWritten);
string resultString = Encoding.UTF8.GetString(resultBytesForDecode).Substring(0, text.Length);
if (resultString == resultStringFromConvert
&& resultBytesForDecode.Slice(0, bytesWritten).SequenceEqual(bytesFromConvert)
&& resultEnum == OperationStatus.Done)
{
totalGood++;
}
else
{
totalFail++;
}
}
}
catch (Exception exc)
{
totalFail++;
Console.WriteLine($"---- EXCEPTION: {text.Length}");
Console.WriteLine($"-- TYPE: {text} {instances} {typeOfTest}");
Console.WriteLine("");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment