Skip to content

[API Proposal]: Base64 parity with Base64Url #121454

@nguerrera

Description

@nguerrera

Background and motivation

The API on Base64Url is very nice. However, there are no equivalents for the things that deal with UTF-16 instead of UTF-8 on Base64 and the UTF-16 base64 functionality on Convert is not as nice.

Here's an example: using Convert, I can't tell if it has failed due to invalid input or destination-too-small. This is actually getting in my way right now in a use case where I want decode only some bytes from base64. I went to copy some code that used Base64Url and was surprised that just dropping the Url suffix didn't work.

using System.Buffers.Text;
using System.Security.Cryptography;

byte[] bytes = new byte[100_000];
RandomNumberGenerator.Fill(bytes);

string base64UrlInput = Base64Url.EncodeToString(bytes);
string base64Input = Convert.ToBase64String(bytes);
string badInput = "@#$!!@#";
byte[] buffer = new byte[1_000];

// Output of TryFromBase64Chars does not distinguish between bad input and destination too small.
{
    Console.WriteLine();
    Console.WriteLine("Bad input vs Convert.TryFromBase64Chars.");
    bool success = Convert.TryFromBase64Chars(badInput, buffer, out int bytesWritten);
    Console.WriteLine("bytesWritten: " + bytesWritten);
    Console.WriteLine("     success: " + success);
}
{
    Console.WriteLine();
    Console.WriteLine("Too much input vs Convert.TryFromBase64Chars");
    bool success = Convert.TryFromBase64Chars(base64Input, buffer, out int bytesWritten);
    Console.WriteLine("bytesWritten: " + bytesWritten);
    Console.WriteLine("     success: " + success);
}

// Output of DecodeFromChars is perfect, but it's only available on Base64Url.
{
    Console.WriteLine();
    Console.WriteLine("Too much input vs Base64Url.DecodeFromChars");
    var status = Base64Url.DecodeFromChars(base64UrlInput, buffer, out int charsConsumed, out int bytesWritten);
    Console.WriteLine("charsConsumed: " + charsConsumed);
    Console.WriteLine(" bytesWritten: " + bytesWritten);
    Console.WriteLine("      status : " + status);
}
{
    Console.WriteLine();
    Console.WriteLine("Bad input vs Base64Url.DecodeFromChars");
    var status = Base64Url.DecodeFromChars(badInput, buffer, out int charsConsumed, out int bytesWritten);
    Console.WriteLine("charsConsumed: " + charsConsumed);
    Console.WriteLine(" bytesWritten: " + bytesWritten);
    Console.WriteLine("      status : " + status);
}

Output:

Bad input vs Convert.TryFromBase64Chars.
bytesWritten: 0
     success: False

Too much input vs Convert.TryFromBase64Chars
bytesWritten: 0
     success: False

Too much input vs Base64Url.DecodeFromChars
charsConsumed: 1332
 bytesWritten: 999
      status : DestinationTooSmall

Bad input vs Base64Url.DecodeFromChars
charsConsumed: 0
 bytesWritten: 0
      status : InvalidData

API Proposal

(Hitting submit early to save a draft and I will come back and populate this with full list of newly proposed API. Basically, it would be to mirror any functionality that's on Base64Url but not Base64 onto Base64.)

API Usage

(Pending)

Alternative Designs

No response

Risks

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    api-suggestionEarly API idea and discussion, it is NOT ready for implementationarea-System.MemoryuntriagedNew issue has not been triaged by the area owner

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions