Base64 question

  • Thread starter Thread starter Jim Brandley
  • Start date Start date
Jon said:
This isn't usually for communicating between two applications though -
it's to allow a stateless application to communicate effectively with
itself. In other words, you're in complete control of both "ends" of
the conversation, so can be compatible with yourself appropriately.
Base64 happens to be a pretty simple format for representing arbitrary
binary data, and it just needs a little tweak for the sake of URL
encoding.

There are always some excuse to break the standards.

It starts with being used for one page communicating with itself. Then
it become used for communicating between pages. Then it starts getting
used down the lower layers. Then it gets exposed as a service to
Java and Python apps. Etc.etc..

Maybe.

Arne
 
Thanks Peter. I'll look into that.

Peter Bromberg said:
Jim,
As Jon Skeet pointed out, modifying the Framework System.Convert classes
may
be the way to go here. A quick decompilation of the System.Convert Base64
methods reveals that :
1) they use unsafe code, which probably accounts for the speed factor.
2) There is a char[] Base64Table used.

So, you could decompile this, create your own (say,
Convert.ToBase64StringUrlSafe) method, and all you would need to do is
change
the values in the Base64table char[] array.
Peter

--
Site: http://www.eggheadcafe.com
UnBlog: http://petesbloggerama.blogspot.com
BlogMetaFinder(BETA): http://www.blogmetafinder.com



Jim Brandley said:
Arne - That was faster - Thanks for the idea. However, Base64 is also
sending out the slash '/' character - that means a second pass with
string.Replace().

BTW - I agree that altering something that complies with a standard is a
bad
thing to do. I was on an ANSI committee years ago, and I know why they
are
built the way they are. However, supplementing that method with an
optimized
conversion is not a bad thing to do. Maybe call it UrlSafeBase64. The
name
would convey the reason for the existance of the method, along with a
pretty
good idea of what the output might be. Just a thought.

Jim
 
That's exactly what I'm using it for. In a stateless environment, I need a
secure way to return context to myself to service http requests coming in
from our own pages. Since I generate a lot of these, it needs to be done
quickly.

Arne Vajhøj said:
Hmm.

People seem already to have forgotten the nightmare of
incompatible uuencode versions.

This isn't usually for communicating between two applications though -
it's to allow a stateless application to communicate effectively with
itself. In other words, you're in complete control of both "ends" of
the conversation, so can be compatible with yourself appropriately.
Base64 happens to be a pretty simple format for representing arbitrary
binary data, and it just needs a little tweak for the sake of URL
encoding.
 
Thanks Arne - That's pretty much what I have written. I was using a
StringBuilder in Encode last night. I was able to cut the cost in half today
by using a char array as you have done. I was surprised at the difference.

Arne Vajhøj said:
Jim said:
BTW - I agree that altering something that complies with a standard is a
bad thing to do. I was on an ANSI committee years ago, and I know why
they are built the way they are. However, supplementing that method with
an optimized conversion is not a bad thing to do. Maybe call it
UrlSafeBase64. The name would convey the reason for the existance of the
method, along with a pretty good idea of what the output might be. Just a
thought.

If you insist in pursuing the idea, then there are some code
attached below which is the fastest code I can write without
unsafe code.

Arne

==================================================='

public class Base64
{
private static char[] EncVals =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".ToCharArray();
private static int[] DecVals;
static Base64()
{
DecVals = new int[128];
for(int i = 0; i < 64; i++)
{
DecVals[EncVals] = i;
}
}
public string Encode(byte[] b)
{
int len = (b.Length * 8 + 5) / 6;
int extra = 3 - (len + 3) % 4;
char[] res = new char[len + extra];
int p = b.Length - b.Length % 3;
int ix = 0;
int tmp;
for(int i = 0; i < p; i += 3)
{
tmp = (b << 16) | (b[i + 1] << 8) | b[i + 2];
res[ix + 3] = EncVals[tmp & 0x3F];
res[ix + 2] = EncVals[(tmp >> 6) & 0x3F];
res[ix + 1] = EncVals[(tmp >> 12) & 0x3F];
res[ix] = EncVals[tmp >> 18];
ix += 4;
}
if(extra == 1)
{
tmp = (b[p] << 16) | (b[p + 1] << 8);
res[ix + 3] = '=';
res[ix + 2] = EncVals[(tmp >> 6) & 0x3F];
res[ix + 1] = EncVals[(tmp >> 12) & 0x3F];
res[ix] = EncVals[tmp >> 18];
}
else if(extra == 2)
{
tmp = b[p] << 16;
res[ix + 3] = '=';
res[ix + 2] = '=';
res[ix + 1] = EncVals[(tmp >> 12) & 0x3F];
res[ix] = EncVals[tmp >> 18];
}
return new String(res);
}
public byte[] Decode(string s)
{
int len = s.Length;
while(s[len - 1] == '=') len--;
len = (len / 4 + 2) * 3;
byte[] res = new byte[len];
int ix = 0;
int tmp;
for(int i = 0; i < s.Length; i += 4)
{
tmp = (DecVals[s] << 18) | (DecVals[s[i + 1]] << 12) |
(DecVals[s[i + 2]] << 6) | DecVals[s[i + 3]];
res[ix] = (byte)(tmp >> 16);
res[ix + 1] = (byte)((tmp >> 8) & 0xFF);
res[ix + 2] = (byte)(tmp & 0xFF);
ix += 3;
}
return res;
}
}
 
Arne Vajhøj said:
There are always some excuse to break the standards.

It starts with being used for one page communicating with itself. Then
it become used for communicating between pages. Then it starts getting
used down the lower layers. Then it gets exposed as a service to
Java and Python apps. Etc.etc..

So you avoid doing that - keep it very tightly controlled, and there
are no problems. I really don't see anything wrong in this case.
 
Jon said:
So you avoid doing that - keep it very tightly controlled, and there
are no problems. I really don't see anything wrong in this case.

How does one prevent code reuse ?

Arne
 
Arne Vajhøj said:
How does one prevent code reuse ?

There's no problem reusing the code - within the appropriate layer.
There's no reason why multiple web applications shouldn't all use the
same code converting URL parameters into arbitrary binary data. You
just need to be careful not to use it inappropriately elsewhere.
Software engineering always requires discipline like that. Naming the
class UrlSafeBase64 or something like that would make it pretty obvious
though, IMO.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top