## C# Base32

I had the need to use Base32 at work some time ago to compress numbers. I had forgotten about it until today when I ran across some old code. As I was researching implementation for a developer on another system we interact with. The problem at the time was that we had numbers that are too big to fit in the field where we needed to write it. In order to do so we needed to compress it and we choose Base32 for the task.

Simply put, you take a number and you convert it to the 32 characters in the convert table, for example.

123456789 becomes VITXVD

Of course when you have the Base32 encoded number you can decode it back to the original number. If you couldn’t do that it wouldn’t be very useful.

VITXVD becomes 123456789

Value | Symbol | Value | Symbol | Value | Symbol | Value | Symbol | |||
---|---|---|---|---|---|---|---|---|---|---|

0 | A | 9 | J | 18 | S | 27 | 3 | |||

1 | B | 10 | K | 19 | T | 28 | 4 | |||

2 | C | 11 | L | 20 | U | 29 | 5 | |||

3 | D | 12 | M | 21 | V | 30 | 6 | |||

4 | E | 13 | N | 22 | W | 31 | 7 | |||

5 | F | 14 | O | 23 | X | |||||

6 | G | 15 | P | 24 | Y | |||||

7 | H | 16 | Q | 25 | Z | |||||

8 | I | 17 | R | 26 | 2 |

Note that one and zero are not used so there is no confusion between them O and I. When shuffling data between different systems, legacy etc they might not be interpreted correctly. You can create the Base32 encoding in different ways. Therefor if your interacting with another system exchanging data that system needs to use the same encoding / decoding as your system.

Below is a C# sample Base32 code.

{

//

private const string BASE_32_ALPHABET = “ABCDEFGHIJKLMNOPQRSTUVWXYZ234567”;

private static int BASE_LENGTH = BASE_32_ALPHABET.Length;

// Encode number to base 32 string

public static string toBase32( int piNumToCode )

{

StringBuilder sRet = new StringBuilder();

// loop until nothing left

do

{

// Set the encoded character using mod

sRet.Append(BASE_32_ALPHABET[piNumToCode % BASE_LENGTH]);

// Adjust the reminder

piNumToCode = piNumToCode / BASE_LENGTH;

}

while (piNumToCode != 0);

return sRet.ToString();

}

// Decode base 32 string to a number

public static int fromBase32(string psCodedString)

{

int iRet = 0;

// Decode the alphabet

for (int i = psCodedString.Length – 1; i > –1; i–)

{ iRet = (iRet * BASE_LENGTH) + BASE_32_ALPHABET.IndexOf(psCodedString[i]); }

return iRet;

}

} // EOC

And unittests

// Make sure encoded number can be decoded correctly

public void randomBase32Test()

{

// Try some random number

string encoded = CxBase32.toBase32(123456789);

Assert.AreEqual(“VITXVD”, encoded);

int decode = CxBase32.fromBase32( encoded );

Assert.AreEqual(123456789, decode);

// Another number just for fun

encoded = CxBase32.toBase32(987654321);

Assert.AreEqual(“RF24N5”, encoded);

decode = CxBase32.fromBase32(encoded);

Assert.AreEqual(987654321, decode);

}

[Test]

// Make sure zero will return a value

public void zeroBase32Test()

{

// Zero test, should return a value as well

string encoded = CxBase32.toBase32(0);

Assert.AreEqual(“A”, encoded);

int decode = CxBase32.fromBase32(encoded);

Assert.AreEqual(0, decode);

}