Subscribe:
|
Categories:
ASP.NET
ast_mono
Asterisk
Code
F#
FreeSWITCH
Guatemala
Humour
IL
Korean
Mei
Misc
Misc. Technology
Personal
Photography
Security
Spammers
VoIP
Sign In
[Giagnocavo]Michael::Write()
Tuesday, January 13, 2004
Base32 in .NET
I haven't seen any .NET Base32 implementations, but various people have expressed interest in having some simpler way to represent binary data (such as an encrypted keycode). So, I'm posting a sample Base32 encoding. Note that this does not conform to the Base32 standard encoding, but uses it's own set of characters (useful for keycodes, where we don't want to have to differentiate between 0 and O. Thanks to Juan Gabriel for making the code much better :).
Update 2004-2-5:
Thanks to
Philippe Cheng
for fixing a bug that caused extra (harmless) output. (See comments for details).
using
System;
using
System.Text;
public
sealed
class
Base32 {
// the valid chars for the encoding
private
static
string
ValidChars =
"QAZ2WSX3"
+
"EDC4RFV5"
+
"TGB6YHN7"
+
"UJM8K9LP"
;
///
<summary>
///
Converts an array of bytes to a Base32-k string.
///
</summary>
public
static
string
ToBase32String(
byte
[] bytes) {
StringBuilder sb =
new
StringBuilder();
// holds the base32 chars
byte
index;
int
hi = 5;
int
currentByte = 0;
while
(currentByte < bytes.Length) {
// do we need to use the next byte?
if
(hi > 8) {
// get the last piece from the current byte, shift it to the right
// and increment the byte counter
index = (
byte
)(bytes[currentByte++] >> (hi - 5));
if
(currentByte != bytes.Length) {
// if we are not at the end, get the first piece from
// the next byte, clear it and shift it to the left
index = (
byte
)(((
byte
)(bytes[currentByte] << (16 - hi)) >> 3) | index);
}
hi -= 3;
}
else
if
(hi == 8) {
index = (
byte
)(bytes[currentByte++] >> 3);
hi -= 3;
}
else
{
// simply get the stuff from the current byte
index = (
byte
)((
byte
)(bytes[currentByte] << (8 - hi)) >> 3);
hi += 5;
}
sb.Append(ValidChars[index]);
}
return
sb.ToString();
}
///
<summary>
///
Converts a Base32-k string into an array of bytes.
///
</summary>
///
<exception cref="System.ArgumentException">
///
Input string
<paramref name="s">
s
</paramref>
contains invalid Base32-k characters.
///
</exception>
public
static
byte
[] FromBase32String(
string
str) {
int
numBytes = str.Length * 5 / 8;
byte
[] bytes =
new
Byte[numBytes];
// all UPPERCASE chars
str = str.ToUpper();
int
bit_buffer;
int
currentCharIndex;
int
bits_in_buffer;
if
(str.Length < 3) {
bytes[0] = (
byte
)(ValidChars.IndexOf(str[0]) | ValidChars.IndexOf(str[1]) << 5);
return
bytes;
}
bit_buffer = (ValidChars.IndexOf(str[0]) | ValidChars.IndexOf(str[1]) << 5);
bits_in_buffer = 10;
currentCharIndex = 2;
for
(
int
i = 0; i < bytes.Length; i++) {
bytes[i] = (
byte
)bit_buffer;
bit_buffer >>= 8;
bits_in_buffer -= 8;
while
(bits_in_buffer < 8 && currentCharIndex < str.Length) {
bit_buffer |= ValidChars.IndexOf(str[currentCharIndex++]) << bits_in_buffer;
bits_in_buffer += 5;
}
}
return
bytes;
}
}
Code
|
Security
Tuesday, January 13, 2004 1:22:46 PM UTC
Comments [3]
|
Trackback
Tracked by:
"http://tpoaef7.biz/james-blunt-lyrics.html" (http://tpoaef7.biz/james-blunt-lyr...
[Pingback]
Thursday, January 29, 2004 11:07:59 PM UTC
I believe there's a bug in the code. It happens when the number of bits is an exact multiple of 5 (a 5 byte array for example) and the algorithm continues even though it ran out of bits. So when you generate Base32 from a 5 byte array it will always append "Q" at the end because Q it at index 0.
The Fix:
In ToBase32String...
if(hi > 8)
{
blah blah
}
// BEGIN INSERTED CODE
else if(hi == 8)
{
index = (byte)(bytes[currentByte++] >> 3);
hi -= 3;
}
// END INSERTED CODE
else
{
blah blah
}
Philippe Cheng
Saturday, January 31, 2004 3:08:49 AM UTC
Holy cannoli! It does have a bug! Thanks for the feedback, Philippe. Mike is surely going to make the changes necessary. All the tests we did were to check for "round trip" correctness, so, this bug never popped up. Nice catch!
-JG
Juan Gabriel Del Cid
|
jdelcidAT NOSPAMatrevido dot net
Thursday, February 05, 2004 10:32:08 PM UTC
Thanks Philippe, I added the fix!
Michael Giagnocavo
|
mggAT NOSPAMAtrevido dot net
Name
E-mail
Home page
Remember Me
Comment (HTML not allowed)
Enter the code shown (prevents robots):
Live Comment Preview