473,395 Members | 1,678 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Base64 question

I need to append a short ciphertext string as a query variable encoded so
it's valid for a URL. After encryption, I convert the bytes to Base64.
However, the result includes characters that are invalid for a URL, notably
'+' symbols. So, I have to cycle the output string through
HttpUtility.UrlEncode(). That takes time. I wrote my own URL-safe Base64
converter in C#, that's about as lean as I can make it. It is much slower
(about 6 times) than the the one provided. However, it runs in about 70% of
the time required to use the standard Base64 converter followed by a trip
through UrlEncode().

I am using .Net 2.0, and I have not found a way to coerce the built in
Base64 converter to use a character set that could avoid the trip through
UrlEncode. Am I missing anything? If not, is there any way to add this
capability to a future release?

Thanks,

Jim Brandley
Jul 7 '07 #1
26 2322
Jim Brandley wrote:
I need to append a short ciphertext string as a query variable encoded so
it's valid for a URL. After encryption, I convert the bytes to Base64.
However, the result includes characters that are invalid for a URL, notably
'+' symbols. So, I have to cycle the output string through
HttpUtility.UrlEncode(). That takes time. I wrote my own URL-safe Base64
converter in C#, that's about as lean as I can make it. It is much slower
(about 6 times) than the the one provided. However, it runs in about 70% of
the time required to use the standard Base64 converter followed by a trip
through UrlEncode().

I am using .Net 2.0, and I have not found a way to coerce the built in
Base64 converter to use a character set that could avoid the trip through
UrlEncode. Am I missing anything? If not, is there any way to add this
capability to a future release?
I find it difficult to believe that URL encoding could have a
noticeable impact on total performance.

Arne
Jul 7 '07 #2
According to the Stopwatch class it did.

"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:46***********************@news.sunsite.dk...
Jim Brandley wrote:
>I need to append a short ciphertext string as a query variable encoded so
it's valid for a URL. After encryption, I convert the bytes to Base64.
However, the result includes characters that are invalid for a URL,
notably '+' symbols. So, I have to cycle the output string through
HttpUtility.UrlEncode(). That takes time. I wrote my own URL-safe Base64
converter in C#, that's about as lean as I can make it. It is much slower
(about 6 times) than the the one provided. However, it runs in about 70%
of the time required to use the standard Base64 converter followed by a
trip through UrlEncode().

I am using .Net 2.0, and I have not found a way to coerce the built in
Base64 converter to use a character set that could avoid the trip through
UrlEncode. Am I missing anything? If not, is there any way to add this
capability to a future release?

I find it difficult to believe that URL encoding could have a
noticeable impact on total performance.

Arne

Jul 8 '07 #3
Jim,
You could consider using HEX instead. This article may provide some ideas:
http://www.eggheadcafe.com/articles/20060427.asp

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

"Jim Brandley" wrote:
I need to append a short ciphertext string as a query variable encoded so
it's valid for a URL. After encryption, I convert the bytes to Base64.
However, the result includes characters that are invalid for a URL, notably
'+' symbols. So, I have to cycle the output string through
HttpUtility.UrlEncode(). That takes time. I wrote my own URL-safe Base64
converter in C#, that's about as lean as I can make it. It is much slower
(about 6 times) than the the one provided. However, it runs in about 70% of
the time required to use the standard Base64 converter followed by a trip
through UrlEncode().

I am using .Net 2.0, and I have not found a way to coerce the built in
Base64 converter to use a character set that could avoid the trip through
UrlEncode. Am I missing anything? If not, is there any way to add this
capability to a future release?

Thanks,

Jim Brandley
Jul 8 '07 #4
Thanks for the response. I already have code in place to convert byte arrays
to hex char arrays. It's fast too. The problem is that it increases the
length of the ciphertext by 50%, and increases the risk of exceeding the
length legal for URLs.

"Peter Bromberg [C# MVP]" <pb*******@yahoo.yabbadabbadoo.comwrote in
message news:B5**********************************@microsof t.com...
Jim,
You could consider using HEX instead. This article may provide some ideas:
http://www.eggheadcafe.com/articles/20060427.asp

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

"Jim Brandley" wrote:
>I need to append a short ciphertext string as a query variable encoded so
it's valid for a URL. After encryption, I convert the bytes to Base64.
However, the result includes characters that are invalid for a URL,
notably
'+' symbols. So, I have to cycle the output string through
HttpUtility.UrlEncode(). That takes time. I wrote my own URL-safe Base64
converter in C#, that's about as lean as I can make it. It is much slower
(about 6 times) than the the one provided. However, it runs in about 70%
of
the time required to use the standard Base64 converter followed by a trip
through UrlEncode().

I am using .Net 2.0, and I have not found a way to coerce the built in
Base64 converter to use a character set that could avoid the trip through
UrlEncode. Am I missing anything? If not, is there any way to add this
capability to a future release?

Thanks,

Jim Brandley

Jul 8 '07 #5
Peter - I did not notice your name when I responded to your previous post. I
have read many of your articles. I like the way you write, and I appreciate
your contribution to the knowledgebase available on the web.

Jim

"Peter Bromberg [C# MVP]" <pb*******@yahoo.yabbadabbadoo.comwrote in
message news:B5**********************************@microsof t.com...
Jim,
You could consider using HEX instead. This article may provide some ideas:
http://www.eggheadcafe.com/articles/20060427.asp

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

"Jim Brandley" wrote:
>I need to append a short ciphertext string as a query variable encoded so
it's valid for a URL. After encryption, I convert the bytes to Base64.
However, the result includes characters that are invalid for a URL,
notably
'+' symbols. So, I have to cycle the output string through
HttpUtility.UrlEncode(). That takes time. I wrote my own URL-safe Base64
converter in C#, that's about as lean as I can make it. It is much slower
(about 6 times) than the the one provided. However, it runs in about 70%
of
the time required to use the standard Base64 converter followed by a trip
through UrlEncode().

I am using .Net 2.0, and I have not found a way to coerce the built in
Base64 converter to use a character set that could avoid the trip through
UrlEncode. Am I missing anything? If not, is there any way to add this
capability to a future release?

Thanks,

Jim Brandley

Jul 8 '07 #6
Jim Brandley wrote:
"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:46***********************@news.sunsite.dk...
>Jim Brandley wrote:
>>I need to append a short ciphertext string as a query variable encoded so
it's valid for a URL. After encryption, I convert the bytes to Base64.
However, the result includes characters that are invalid for a URL,
notably '+' symbols. So, I have to cycle the output string through
HttpUtility.UrlEncode(). That takes time. I wrote my own URL-safe Base64
converter in C#, that's about as lean as I can make it. It is much slower
(about 6 times) than the the one provided. However, it runs in about 70%
of the time required to use the standard Base64 converter followed by a
trip through UrlEncode().

I am using .Net 2.0, and I have not found a way to coerce the built in
Base64 converter to use a character set that could avoid the trip through
UrlEncode. Am I missing anything? If not, is there any way to add this
capability to a future release?
I find it difficult to believe that URL encoding could have a
noticeable impact on total performance.
According to the Stopwatch class it did.
Stopwatch a load simulator program ?

Arne
Jul 8 '07 #7
Jim Brandley wrote:
I need to append a short ciphertext string as a query variable encoded so
it's valid for a URL. After encryption, I convert the bytes to Base64.
However, the result includes characters that are invalid for a URL, notably
'+' symbols. So, I have to cycle the output string through
HttpUtility.UrlEncode(). That takes time. I wrote my own URL-safe Base64
converter in C#, that's about as lean as I can make it. It is much slower
(about 6 times) than the the one provided. However, it runs in about 70% of
the time required to use the standard Base64 converter followed by a trip
through UrlEncode().
I believe that + is the only non URL valid character in base64 output.

Why not a simple String Replace ?
I am using .Net 2.0, and I have not found a way to coerce the built in
Base64 converter to use a character set that could avoid the trip through
UrlEncode. Am I missing anything? If not, is there any way to add this
capability to a future release?
Base64 is a standard. It is not common to allow mocking with a standard.

Arne
Jul 8 '07 #8
I'll try that and see what it costs. I was hoping to avoid another iteration
through the characters in the string.

"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:46***********************@news.sunsite.dk...
Jim Brandley wrote:
>I need to append a short ciphertext string as a query variable encoded so
it's valid for a URL. After encryption, I convert the bytes to Base64.
However, the result includes characters that are invalid for a URL,
notably '+' symbols. So, I have to cycle the output string through
HttpUtility.UrlEncode(). That takes time. I wrote my own URL-safe Base64
converter in C#, that's about as lean as I can make it. It is much slower
(about 6 times) than the the one provided. However, it runs in about 70%
of the time required to use the standard Base64 converter followed by a
trip through UrlEncode().

I believe that + is the only non URL valid character in base64 output.

Why not a simple String Replace ?
>I am using .Net 2.0, and I have not found a way to coerce the built in
Base64 converter to use a character set that could avoid the trip through
UrlEncode. Am I missing anything? If not, is there any way to add this
capability to a future release?

Base64 is a standard. It is not common to allow mocking with a standard.

Arne

Jul 8 '07 #9
It is a new (to 2.0) class in System.Diagnostics. It is easy to use and is
useful when comparing the performance of different approaches to solving a
problem.

"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:46***********************@news.sunsite.dk...
Jim Brandley wrote:
>"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:46***********************@news.sunsite.dk. ..
>>Jim Brandley wrote:
I need to append a short ciphertext string as a query variable encoded
so it's valid for a URL. After encryption, I convert the bytes to
Base64. However, the result includes characters that are invalid for a
URL, notably '+' symbols. So, I have to cycle the output string through
HttpUtility.UrlEncode(). That takes time. I wrote my own URL-safe
Base64 converter in C#, that's about as lean as I can make it. It is
much slower (about 6 times) than the the one provided. However, it runs
in about 70% of the time required to use the standard Base64 converter
followed by a trip through UrlEncode().

I am using .Net 2.0, and I have not found a way to coerce the built in
Base64 converter to use a character set that could avoid the trip
through UrlEncode. Am I missing anything? If not, is there any way to
add this capability to a future release?
I find it difficult to believe that URL encoding could have a
noticeable impact on total performance.
According to the Stopwatch class it did.

Stopwatch a load simulator program ?

Arne

Jul 8 '07 #10
Jim Brandley wrote:
"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:46***********************@news.sunsite.dk...
>Jim Brandley wrote:
>>"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:46***********************@news.sunsite.dk.. .
Jim Brandley wrote:
I need to append a short ciphertext string as a query variable encoded
so it's valid for a URL. After encryption, I convert the bytes to
Base64. However, the result includes characters that are invalid for a
URL, notably '+' symbols. So, I have to cycle the output string through
HttpUtility.UrlEncode(). That takes time. I wrote my own URL-safe
Base64 converter in C#, that's about as lean as I can make it. It is
much slower (about 6 times) than the the one provided. However, it runs
in about 70% of the time required to use the standard Base64 converter
followed by a trip through UrlEncode().
>
I am using .Net 2.0, and I have not found a way to coerce the built in
Base64 converter to use a character set that could avoid the trip
through UrlEncode. Am I missing anything? If not, is there any way to
add this capability to a future release?
I find it difficult to believe that URL encoding could have a
noticeable impact on total performance.
According to the Stopwatch class it did.
Stopwatch a load simulator program ?
It is a new (to 2.0) class in System.Diagnostics. It is easy to use
and is
useful when comparing the performance of different approaches to
solving a
problem.
Is it ?

Try think about this.

You can do about 1 million conversions to base64 of
a small string in 1 second

=>

If your web server is CPU bound at about 1000 requests/second,
then the base64 conversion is using 0.1% of your CPU and something
else is chewing the other 99.9%.

Arne

Jul 8 '07 #11
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
"Jim Brandley" <Ji**********@IntercimNOSPAM.comwrote in message
news:eF**************@TK2MSFTNGP06.phx.gbl...
I'll try that and see what it costs. I was hoping to avoid another
iteration through the characters in the string.

"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:46***********************@news.sunsite.dk...
>Jim Brandley wrote:
>>I need to append a short ciphertext string as a query variable encoded
so it's valid for a URL. After encryption, I convert the bytes to
Base64. However, the result includes characters that are invalid for a
URL, notably '+' symbols. So, I have to cycle the output string through
HttpUtility.UrlEncode(). That takes time. I wrote my own URL-safe Base64
converter in C#, that's about as lean as I can make it. It is much
slower (about 6 times) than the the one provided. However, it runs in
about 70% of the time required to use the standard Base64 converter
followed by a trip through UrlEncode().

I believe that + is the only non URL valid character in base64 output.

Why not a simple String Replace ?
>>I am using .Net 2.0, and I have not found a way to coerce the built in
Base64 converter to use a character set that could avoid the trip
through UrlEncode. Am I missing anything? If not, is there any way to
add this capability to a future release?

Base64 is a standard. It is not common to allow mocking with a standard.

Arne


Jul 8 '07 #12
I did not mean to imply this was a bottleneck. I strive to prevent the
creation of bottlenecks - easier to do that than track them down later. I'm
working on a very large (to me anyway - approx 2M lines of C#, not counting
aspx and ascx pages) web app for intranets. Pages are generated with maybe
2% static text and 98% dynamic, and can have 1500 to 1700 users at any given
time. It is primarily presenting and recording real-time information in
large manufacturing environments.

Responsiveness is a big deal for our customers. I spend all my time in the
business objects, data layer and writing SQL. I very seldom do anything with
screens, except present the information they need for binding. Any time I
write a bit of code that gets executed with any frequency, I try to find the
time to analyze it carefully and shave whatever I can.
"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:46***********************@news.sunsite.dk...
Jim Brandley wrote:
>"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:46***********************@news.sunsite.dk. ..
>>Jim Brandley wrote:
"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:46***********************@news.sunsite.dk. ..
Jim Brandley wrote:
>I need to append a short ciphertext string as a query variable
>encoded so it's valid for a URL. After encryption, I convert the
>bytes to Base64. However, the result includes characters that are
>invalid for a URL, notably '+' symbols. So, I have to cycle the
>output string through HttpUtility.UrlEncode(). That takes time. I
>wrote my own URL-safe Base64 converter in C#, that's about as lean as
>I can make it. It is much slower (about 6 times) than the the one
>provided. However, it runs in about 70% of the time required to use
>the standard Base64 converter followed by a trip through UrlEncode().
>>
>I am using .Net 2.0, and I have not found a way to coerce the built
>in Base64 converter to use a character set that could avoid the trip
>through UrlEncode. Am I missing anything? If not, is there any way to
>add this capability to a future release?
I find it difficult to believe that URL encoding could have a
noticeable impact on total performance.
According to the Stopwatch class it did.
Stopwatch a load simulator program ?
It is a new (to 2.0) class in System.Diagnostics. It is easy to use
and is
useful when comparing the performance of different approaches to
solving a
problem.

Is it ?

Try think about this.

You can do about 1 million conversions to base64 of
a small string in 1 second

=>

If your web server is CPU bound at about 1000 requests/second,
then the base64 conversion is using 0.1% of your CPU and something
else is chewing the other 99.9%.

Arne

Jul 8 '07 #13
Arne Vajhøj <ar**@vajhoej.dkwrote:
Jim Brandley wrote:
I need to append a short ciphertext string as a query variable encoded so
it's valid for a URL. After encryption, I convert the bytes to Base64.
However, the result includes characters that are invalid for a URL, notably
'+' symbols. So, I have to cycle the output string through
HttpUtility.UrlEncode(). That takes time. I wrote my own URL-safe Base64
converter in C#, that's about as lean as I can make it. It is much slower
(about 6 times) than the the one provided. However, it runs in about 70% of
the time required to use the standard Base64 converter followed by a trip
through UrlEncode().
I believe that + is the only non URL valid character in base64 output.
Depending on the exact context, it can be handy to get rid of / and =
too. In some cases it's just + that needs to be replaced though, yes.
Why not a simple String Replace ?
Indeed... possibly with a check to see whether a replacement is needed
to start with.
I am using .Net 2.0, and I have not found a way to coerce the built in
Base64 converter to use a character set that could avoid the trip through
UrlEncode. Am I missing anything? If not, is there any way to add this
capability to a future release?
Base64 is a standard. It is not common to allow mocking with a standard.
I think it's pretty common to adapt base64 to only include URL-safe
characters. Put it this way - it's common enough to have made it into
Wikipedia:

http://en.wikipedia.org/wiki/Base64#URL_Applications

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jul 8 '07 #14
Jon Skeet [C# MVP] wrote:
>Base64 is a standard. It is not common to allow mocking with a standard.

I think it's pretty common to adapt base64 to only include URL-safe
characters. Put it this way - it's common enough to have made it into
Wikipedia:

http://en.wikipedia.org/wiki/Base64#URL_Applications
Hmm.

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

:-(

Arne
Jul 8 '07 #15
Thanks. That's similar to what I have written. I'll see if I can get mine to
perform better. I was using a StringBuilder to accept the encoded
characters. I'll see if it performs better using a character array, and save
the string construction until it's complete.

"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP*********************@msnews.microsoft.com. ..
Arne Vajhøj <ar**@vajhoej.dkwrote:
Jim Brandley wrote:
I need to append a short ciphertext string as a query variable encoded
so
it's valid for a URL. After encryption, I convert the bytes to Base64.
However, the result includes characters that are invalid for a URL,
notably
'+' symbols. So, I have to cycle the output string through
HttpUtility.UrlEncode(). That takes time. I wrote my own URL-safe Base64
converter in C#, that's about as lean as I can make it. It is much
slower
(about 6 times) than the the one provided. However, it runs in about 70%
of
the time required to use the standard Base64 converter followed by a
trip
through UrlEncode().

I believe that + is the only non URL valid character in base64 output.
Depending on the exact context, it can be handy to get rid of / and =
too. In some cases it's just + that needs to be replaced though, yes.
Why not a simple String Replace ?
Indeed... possibly with a check to see whether a replacement is needed
to start with.
I am using .Net 2.0, and I have not found a way to coerce the built in
Base64 converter to use a character set that could avoid the trip
through
UrlEncode. Am I missing anything? If not, is there any way to add this
capability to a future release?

Base64 is a standard. It is not common to allow mocking with a standard.
I think it's pretty common to adapt base64 to only include URL-safe
characters. Put it this way - it's common enough to have made it into
Wikipedia:

http://en.wikipedia.org/wiki/Base64#URL_Applications

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jul 8 '07 #16
Arne Vajhøj <ar**@vajhoej.dkwrote:
Jon Skeet [C# MVP] wrote:
Base64 is a standard. It is not common to allow mocking with a standard.
I think it's pretty common to adapt base64 to only include URL-safe
characters. Put it this way - it's common enough to have made it into
Wikipedia:

http://en.wikipedia.org/wiki/Base64#URL_Applications
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.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jul 8 '07 #17
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" wrote:
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
"Jim Brandley" <Ji**********@IntercimNOSPAM.comwrote in message
news:eF**************@TK2MSFTNGP06.phx.gbl...
I'll try that and see what it costs. I was hoping to avoid another
iteration through the characters in the string.

"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:46***********************@news.sunsite.dk...
Jim Brandley wrote:
I need to append a short ciphertext string as a query variable encoded
so it's valid for a URL. After encryption, I convert the bytes to
Base64. However, the result includes characters that are invalid for a
URL, notably '+' symbols. So, I have to cycle the output string through
HttpUtility.UrlEncode(). That takes time. I wrote my own URL-safe Base64
converter in C#, that's about as lean as I can make it. It is much
slower (about 6 times) than the the one provided. However, it runs in
about 70% of the time required to use the standard Base64 converter
followed by a trip through UrlEncode().

I believe that + is the only non URL valid character in base64 output.

Why not a simple String Replace ?

I am using .Net 2.0, and I have not found a way to coerce the built in
Base64 converter to use a character set that could avoid the trip
through UrlEncode. Am I missing anything? If not, is there any way to
add this capability to a future release?

Base64 is a standard. It is not common to allow mocking with a standard.

Arne


Jul 9 '07 #18
Jim Brandley wrote:
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 =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw xyz0123456789+/".ToCharArray();
private static int[] DecVals;
static Base64()
{
DecVals = new int[128];
for(int i = 0; i < 64; i++)
{
DecVals[EncVals[i]] = 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[i] << 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[i]] << 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;
}
}
Jul 9 '07 #19
Jim Brandley wrote:
"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
>You can do about 1 million conversions to base64 of
a small string in 1 second

=>

If your web server is CPU bound at about 1000 requests/second,
then the base64 conversion is using 0.1% of your CPU and something
else is chewing the other 99.9%.
I did not mean to imply this was a bottleneck. I strive to prevent the
creation of bottlenecks - easier to do that than track them down
later. I'm
working on a very large (to me anyway - approx 2M lines of C#, not
counting
aspx and ascx pages) web app for intranets. Pages are generated with
maybe
2% static text and 98% dynamic, and can have 1500 to 1700 users at
any given
time. It is primarily presenting and recording real-time information in
large manufacturing environments.

Responsiveness is a big deal for our customers. I spend all my time
in the
business objects, data layer and writing SQL. I very seldom do
anything with
screens, except present the information they need for binding. Any
time I
write a bit of code that gets executed with any frequency, I try to
find the
time to analyze it carefully and shave whatever I can.
I still don't think it is worth it.

You should write 95%-98% of your code with priority of easy maintenance
and then optimize the 2%-5% of your code that has been proven to impact
performance for speed.

Writing clever code that optimizes stuff that does not need to be
optimized does not reduce hardware costs but will increase maintenance
costs dramatically.

Simple code is usually better than clever code when we talk business.

I used to do a lot that type of micro optimizations in the 1980's. But
not any more.

I think you should use the framework methods and just consider the
optimized code an interesting academic exercise.

Arne

Jul 9 '07 #20
Jon Skeet [C# MVP] wrote:
Arne Vajhøj <ar**@vajhoej.dkwrote:
>Jon Skeet [C# MVP] wrote:
>>>Base64 is a standard. It is not common to allow mocking with a standard.
I think it's pretty common to adapt base64 to only include URL-safe
characters. Put it this way - it's common enough to have made it into
Wikipedia:

http://en.wikipedia.org/wiki/Base64#URL_Applications
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.
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
Jul 9 '07 #21
Thanks Peter. I'll look into that.

"Peter Bromberg [C# MVP]" <pb*******@yahoo.yabbadabbadoo.comwrote in
message news:3A**********************************@microsof t.com...
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" wrote:
>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
"Jim Brandley" <Ji**********@IntercimNOSPAM.comwrote in message
news:eF**************@TK2MSFTNGP06.phx.gbl...
I'll try that and see what it costs. I was hoping to avoid another
iteration through the characters in the string.

"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:46***********************@news.sunsite.dk...
Jim Brandley wrote:
I need to append a short ciphertext string as a query variable
encoded
so it's valid for a URL. After encryption, I convert the bytes to
Base64. However, the result includes characters that are invalid for
a
URL, notably '+' symbols. So, I have to cycle the output string
through
HttpUtility.UrlEncode(). That takes time. I wrote my own URL-safe
Base64
converter in C#, that's about as lean as I can make it. It is much
slower (about 6 times) than the the one provided. However, it runs in
about 70% of the time required to use the standard Base64 converter
followed by a trip through UrlEncode().

I believe that + is the only non URL valid character in base64 output.

Why not a simple String Replace ?

I am using .Net 2.0, and I have not found a way to coerce the built
in
Base64 converter to use a character set that could avoid the trip
through UrlEncode. Am I missing anything? If not, is there any way to
add this capability to a future release?

Base64 is a standard. It is not common to allow mocking with a
standard.

Arne




Jul 9 '07 #22
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.

"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP*********************@msnews.microsoft.com. ..
Arne Vajhøj <ar**@vajhoej.dkwrote:
Jon Skeet [C# MVP] wrote:
Base64 is a standard. It is not common to allow mocking with a
standard.
I think it's pretty common to adapt base64 to only include URL-safe
characters. Put it this way - it's common enough to have made it into
Wikipedia:

http://en.wikipedia.org/wiki/Base64#URL_Applications

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.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jul 9 '07 #23
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" <ar**@vajhoej.dkwrote in message
news:46***********************@news.sunsite.dk...
Jim Brandley wrote:
>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 =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw xyz0123456789+/".ToCharArray();
private static int[] DecVals;
static Base64()
{
DecVals = new int[128];
for(int i = 0; i < 64; i++)
{
DecVals[EncVals[i]] = 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[i] << 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[i]] << 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;
}
}

Jul 9 '07 #24
Arne Vajhøj <ar**@vajhoej.dkwrote:
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..
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 Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jul 9 '07 #25
Jon Skeet [C# MVP] wrote:
Arne Vajhøj <ar**@vajhoej.dkwrote:
>>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..

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
Jul 15 '07 #26
Arne Vajhøj <ar**@vajhoej.dkwrote:
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 ?
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.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jul 15 '07 #27

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: John | last post by:
Hi all, I've been going through google and yahoo looking for a certain base64 decoder in C without success. What I'm after is something that you can pass a base64 encoded string into and get back...
1
by: Jeremy Moncho | last post by:
Hello! I am toying with base64 conversion, (which I haven't used before). I wrote a dll that handles the in/out conversion for a windows form assembly. My question is, once a stream has ...
5
by: LP | last post by:
A web service returns base64 encoded data. The goal is to parse it and store it into binary file with .dat extension. This file is then will be used by a custom program to produce diagrams. As far...
7
by: Neo Geshel | last post by:
Greetings. I have managed to stitch together an awesome method of posting text along with an image to a database, in a way that allows an unlimited number of previews to ensure that text and...
0
by: Michele Petrazzo | last post by:
Hi ng, I see that after en encoding with base64, the memory used for the variable that I use for store the encoded data, after deleted, python keep a part of that memory: #ls -lh on...
14
by: BB | last post by:
Hello. i am trying to decode a block of (what i think is) base64 into text, and i have NO idea how to begin. I'm going to paste the whole string here, but i want to know the steps necessary to...
2
by: Lonewolf | last post by:
Hi all, please pardon me if this question is too trivial. I have an XML file which stores data in base64. The schema is something like this, <Remokon> <Brand Name="SONY"> <Model Name="Type 1",...
4
by: Tamir Weiss | last post by:
I'm trying to send a byte array (JPG image) from javascript to a servlet for processing. I'm using Base64 to encode the byte array in javascript, and then a base64 decoder in the servlet to decode...
13
by: aruna.eies.eng | last post by:
i am currently trying to convert data into binary data.for that i need to know how to achieve it in c language and what are the libraries that we can use. so if any one can send me a sample code or...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.