views:

1221

answers:

4

I need to encode/decode an integer which is up to 9 digits long but most often 7 digits long. I'd like to make it easier to communicate/memorise - it will be communicated by phone, copied & pasted, keyed in from a card/memory/label, hand-written on labels and generally abused!

I'm looking to reduce the number of digits (whilst adding a checksum) using a base 32 scheme. I'm most in favour of z-base-32 (over the RFC4648 implementation) because of some of the design goals (e.g. handwriting) and choice of alphabet (lower-case, permuted to favour characters that are easier to read, write, speak, and remember). However, I can't find a C# implementation and I'm concerned about porting from the existing Python implementation.

Does anyone have a C# implementation? Alternatively, does anyone have a set of test cases (other than the examples in the spec) that I can use to validate a port?

I'm open to suggestions about alternative encoding schemes.

+2  A: 

If you look at your cell phone keyboard, the number 1985239 can be represented using these characters (a,b,c), (w,x,y,z), (t,u,v), ... Try to find an algorithm that would generate more-or-less English-like words given an ordered set of unordered sets of characters -- these will be easier to memorize.

Anton Gogolev
+1. Good idea. If a dictionary has 50,000 words in it, two words would cover your number space.
Dead account
@Ian: Interesting idea.. you could just do a word<->number mapping. you're right, 2 words gives 2.5 B combos. just have to make sure to filter out the profanity :)
Mark
+2  A: 

You might want to use your own encode / decode routine?

Encode:

 string acceptedChar = "ABCDEFGHJKLMNPQRSTUWXZ0123456789";
 int yourNumber = 12345678;

 string response = "";
 while (yourNumber > 0)
 {
      response += acceptedChar[yourNumber % acceptedChar.Length];
      yourNumber /= acceptedChar.Length;
 }

Decode:

 string acceptedChar = "ABCDEFGHJKLMNPQRSTUWXZ0123456789";
 string inputStr = "ABCD";

 int yourNumber = 0;
 for (int i = inputStr.Length; i > 0; i--)
 {
     yourNumber *= acceptedChar.Length;
     yourNumber += acceptedChar.IndexOf(inputStr[i]);
 }

(Untested code)

Dead account
I think your encoding routine needs to be changed to have: response = acceptedChar[yourNumber % acceptedChar.Length] + response;
dommer
+1  A: 

This project looks like what you're after:

Base 36 type for .NET (C#)

dommer
Would suggest base 33, to avoid 5 vs S, 0 vs O and 1 vs I confusions.
Richard
+3  A: 

Here is one implementation of zBase32 encoding on .NET platform (written in C#).

Hemant
Excellent, I'll read your blog article and take a look at the code, thanks.
Robin M