What is the difference between Convert.ToBase64String(byte[]) and HttpServerUtility.UrlTokenEncode(byte[])?
Asked Answered
G

2

11

I'm trying to remove a dependence on System.Web.dll from a Web API project, but have stumbled on a call to HttpServerUtility.UrlTokenEncode(byte[] input) (and its corresponding decode method) that I don't know what to replace with to ensure backwards compatibility. The documentation says that this method

Encodes a byte array into its equivalent string representation using base 64 digits, which is usable for transmission on the URL.

I tried substituting with Convert.ToBase64String(byte[] input) (and its corresponding decode method), which is very similarly described in the docs:

Converts an array of 8-bit unsigned integers to its equivalent string representation that is encoded with base-64 digits.

However, they don't seem to be entirely equivalent; when using Convert.FromBase64String(string input) to decode a string encoded with HttpServerUtility, I get an exception stating

The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.

What is the difference between these two conversion utilities? What's the correct way to remove this dependence on System.Web.HttpServerUtility?


Some users have suggested that this is a duplicate of this one, but I disagree. That question is about base-64-encoding a string in a url-safe manner in general, but I need to reproduce the exact behavior of HttpServerUtility but without a dependency on System.Web.

Gavingavini answered 16/2, 2016 at 10:32 Comment(2)
You could take a look at the source, might shed some light.Gamb
Possible duplicate of How to achieve Base64 URL safe encoding in C#?Tb
G
16

I took DGibbs on their word and Used the Source. It turns out the following happens in the HttpServerUtility methods:

Encoding to Base64

  1. Use System.Convert to convert the input to Base64.

  2. Replace + by - and / by _. Example: Foo+bar/=== becomes Foo-bar_===.

  3. Replace any number of = at the end of the string, with an integer denoting how many they were. Example: Foo-bar_=== becomes Foo-bar_3.

Decoding from Base64

  1. Replace the digit at the end of the string by the same number of = signs. Example: Foo-bar_3 becomes Foo-bar_===.

  2. Replace - by + and _ by /. Example: Foo-bar_=== becomes Foo+bar/===.

  3. Use System.Convert to decode the preprocessed input from Base64.

Gavingavini answered 16/2, 2016 at 14:51 Comment(1)
It should also be noted that the number at the end is required - i.e. no = signs will append 0 to the output/interpreted from the input.Osborne
Q
4

HttpServerUtility.UrlTokenEncode(byte[] input) will encode a URL safe Base64 string. In Base64 +, / and = characters are valid, but they are not URL safe, this method will replace these characters whereas the Convert.ToBase64String(byte[] input) will not. You can probably drop the reference and do it yourself.

Usually, '+' is replaced with '-' and '/' with '_' padding '=' is just removed.

Accepted answer here gives a code example: How to achieve Base64 URL safe encoding in C#?

Quadrennium answered 16/2, 2016 at 10:53 Comment(1)
This is actually not entirely correct. Padding = aren't removed, they're replaced with an integer denoting their count. In other words, blah== becomes blah2, not blah. (Found this out from looking at the source).Gavingavini

© 2022 - 2024 — McMap. All rights reserved.