views:

4181

answers:

2

I want to base64 encode data to put it in a URL and then decode it within my HttpHandler.

I have found that Base64 Encoding allows for a '/' character which will mess up my UriTemplate matching. Then I found that there is a concept of a "modified Base64 for URL" from wikipedia:

A modified Base64 for URL variant exists, where no padding '=' will be used, and the '+' and '/' characters of standard Base64 are respectively replaced by '-' and '_', so that using URL encoders/decoders is no longer necessary and has no impact on the length of the encoded value, leaving the same encoded form intact for use in relational databases, web forms, and object identifiers in general.

Using .NET I want to modify my current code from doing basic base64 encoding and decoding to using the "modified base64 for URL" method. Has anyone done this?

To decode, I know it starts out with something like:

string base64EncodedText = base64UrlEncodedText.Replace('-', '+').Replace('_', '/');

// Append '=' char(s) if necessary - how best to do this?

// My normal base64 decoding now uses encodedText

But, I need to potentially add one or two '=' chars to the end which looks a little more complex.

My encoding logic should be a little simpler:

// Perform normal base64 encoding
byte[] encodedBytes = Encoding.UTF8.GetBytes(unencodedText);
string base64EncodedText = Convert.ToBase64String(encodedBytes);

// Apply URL variant
string base64UrlEncodedText = base64EncodedText.Replace("=", String.Empty).Replace('+', '-').Replace('/', '_');

I have seen the Guid to Base64 for URL StackOverflow entry, but that has a known length and therefore they can hardcode the number of equal signs needed at the end.

+5  A: 

This ought to pad it out correctly:-

 base64 = base64.PadRight(base64.Length + (4 - base64.Length % 4) % 4, '=');
AnthonyWJones
Bah, you beat me. I'll just delete my post cause it looks almost like I copied you :)
AaronLS
Won't this add up to three '=' chars? It appears that there will only be 0, 1, or 2 of these.
Kirk Liemohn
@Kirk: If it adds 3 characters then the base64 string is already corrupt. I guess it would be a good idea to validate the string, it should only contain the characters expected and Length % 4 != 3.
AnthonyWJones
Slick - thanks for the details. I didn't realize that.
Kirk Liemohn
Hmmm. In trying this out, it isn't doing the trick. Still looking for answers. The number of equal signs just isn't panning out properly.
Kirk Liemohn
Oops needed to invert the modulo.
AnthonyWJones
That did the trick - excellent work!
Kirk Liemohn
+6  A: 

Also check class HttpServerUtility with UrlTokenEncode and UrlTokenDecode methods that is handling URL safe Base64 encoding and decoding.

///<summary>
/// Base 64 Encoding with URL and Filename Safe Alphabet using UTF-8 character set.
///</summary>
///<param name="str">The origianl string</param>
///<returns>The Base64 encoded string</returns>
public static string Base64Encode(string str)
{
    byte[] encbuff = Encoding.UTF8.GetBytes(str);
    return HttpServerUtility.UrlTokenEncode(encbuff);
}
///<summary>
/// Decode Base64 encoded string with URL and Filename Safe Alphabet using UTF-8.
///</summary>
///<param name="str">Base64 code</param>
///<returns>The decoded string.</returns>
public static string Base64Decode(string str)
{
    byte[] decbuff = HttpServerUtility.UrlTokenDecode(str);
    return Encoding.UTF8.GetString(decbuff);
}
Fredrik Haglund
Thanks for the tip. I'll try that next time!
Kirk Liemohn
Your tip was the glorious end to an multi hour and hair tuft search for the answer. thanks
Praesagus
This does the trick...
Timothy Lee Russell