.NET base64 decoding workaround

Nikita Fedorov
2 min readJul 29, 2019

The story is not really long. I was trying to complete one of my tasks when I realized that there is an odd behavior of the base64 string decoding in .NET C#. You are familiar with this function, right?

byte[] bytes = Convert.FromBase64String(text);

And here is the problem: when you want to use your encoded text as part of some URL you want to avoid some of the characters allowed in base64: ‘+’ , ‘/’ and ‘=’. The common practice is to replace ‘+’ with ‘-’, ‘/’ with ‘_’ and trim all the equal signs from the end of the decoded string. You can google the process of the encoding, I’ll just say that equal sign represents the “white space” in the decoded string. The base64 encoding takes each 3 bytes (each 3 characters) and produces the 4 ASCII characters for them. In other words: if your source string contains number of characters which can be divided to 3 without remainder, there will be no equal signs at the end. But for other cases there will be.

It would be really helpful if .NET function will restore the equal signs by itself, but it’s not happening:

[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(“abcd”)) // -> YWJjZA==
$test = "YWJjZA"
[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($test)) // -> Invalid length for a Base-64 char array or string.
$test = "YWJjZA=="
[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($test)) // -> abcd

The same is for C#. If you want to use your encoded string as part of a URL you’re doing something like this:

var bytes = Encoding.UTF8.GetBytes(source);
var encodedUrlFriendly = Convert.ToBase64String(bytes).TrimEnd(‘=’).Replace(‘+’, ‘-’).Replace(‘/’, ‘_’);

Now you want to restore your source string on the server (or whatever place). I don’t pretend to provide the perfect solution, but this can save you some time:

encoded = encoded.Replace(‘-’, ‘+’).Replace(‘_’, ‘/’);
var d = encoded.Length % 4;
if (d != 0)
{
encoded = encoded.TrimEnd(‘=’);
encoded += d % 2 > 0 ? “=” : “==”;
}
byte[] bytes = Convert.FromBase64String(encoded);
var decoded = Encoding.UTF8.GetString(bytes);

Hope that will help somebody.

p.s.: .NET team, please fix this at last :D

--

--