views:

494

answers:

4

Hello,

I'm working on a quick captcha generator for a simple site I'm putting together, and I'm hoping to pass an encrypted key in the url of the page. I could probably do this as a query string parameter easy enough, but I'm hoping not too (just because nothing else runs off the query string)...

My encryption code produces a byte[], which is then transformed using Convert.ToBase64String(byte[]) into a string. This string, however, is still not quite url friendly, as it can contain things like '/' and '='. Does anyone know of a better function in the .NET framework to convert a byte array to a url friendly string?

I know all about System.Web.HttpUtility.UrlEncode() and its equivalents, however, they only work properly with query string parameters. If I url encode an '=' inside of the path, my web server brings back a 400 Bad Request error.

Anyways, not a critical issue, but hoping someone can give me a nice solution

**EDIT: Just to be absolutely sure exactly what I'm doing with the string, I figured I would supply a little more information.

The byte[] that results from my encryption algorithm should be fed through some sort of algorithm to make it into a url friendly string. After this, it becomes the content of an XElement, which is then used as the source document for an XSLT transformation, and is used as a part of the href attribute for an anchor. I don't believe the xslt transformation is causing the issues, since what is coming through on the path appears to be an encoded query string parameter, but causes the HTTP 400

I've also tried HttpUtility.UrlPathEncode() on a base64 string, but that doesn't seem to do the trick either (I still end up with '/'s in my url)**

+1  A: 

Have a look at System.BitConverter.ToString(myByteArray)

Handy for one way encoding for things like hashes but as pointed out by ssg it's not very efficient. I wouldn't recommend it for large amounts of data.

David G
I'm willing to go to Hex Encoding, if there is a function to reverse this operation...
LorenVS
For Reference, BitConverter.GetBytes() doesn't have an overload which takes a string
LorenVS
Found this url for reference http://stackoverflow.com/questions/1230303/bitconverter-tostring-in-reverse will just use this solution
LorenVS
You need to keep in mind that this is very inefficient for transferring binary data. Data grows 300% this way instead of 130% as in base64.
ssg
@ssg - actually it grows to twice its size, not 4 times its size (2 chars per byte)
orip
@orip: That's right. I thought of the original form with hyphens.
ssg
A: 

Base64 has these characters: +, /, =

Step 1: Trim away the "="s since they are used for padding the output. str.Trim(new char[] {'='});. Base64 decoder should be able to get away without them.

Step 2: "/" is ok in the URL string in the query section (after "?"). i.e. http://www.google.com/?q=/some/ (Request.QueryString["q"] == "/some/"). EDIT: You mentioned the string is in path, then you have to do anohter replace for "/" to "%2F".

Step 3: Replace "+"s with "%2B". str.Replace("+", "%2B");

So final code would be:

str = str.Trim(new char[] {'='}).Replace("+", "%2B").Replace("/", "%2F");

You're done.

ssg
Except I'm not in the querystring, I'm inside the path
LorenVS
Edited it out for that need but a formal URL encoder is more and more appropriate after each .replace :)
ssg
Would probably work for met at this point, but (you must agree with this) I have to give it to the guy with the UrlTokenEncode function...
LorenVS
You should note that `System.Uri` will deserialize "%2F" in path portions, as was it just a '/': https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=511010
troethom
@troethom: Didn't know that, thanks! Then a %252F would be in place instead.
ssg
A: 

if you're working on a quick captcha for a simple site you're putting together, why are you writing it from scratch instead of using something that has been tried and tested like recaptcha?

adrianos
b/c it doesn't have to be perfect... It just has to work, and its an educational thing. I've never written a captcha before, figure it would be worth a shot... It's just for a personal site, nothing fancy
LorenVS
+8  A: 

You're looking for HttpServerUtility.UrlTokenEncode and HttpServerUtility.UrlTokenDecode, in System.Web.

They encode in base64, replacing the potentially dangerous '+' and '/' chars with '-' and '_' instead.

MSDN documentation

orip
Seriously? I must try this now...
LorenVS
+1: Base64 is a more compact encoding than just using the hex digits from `BitConverter.ToString`.
LukeH
Worked like a charm... Wicked (little known) function there... Thanks man
LorenVS
@LorenVS - sure. I didn't know it was there either, until we stumbled on it at work and replaced our own implementation with it.
orip