Friday, April 29, 2011

Encoding a number, C# implementation of z-base-32 or something else?

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.

From stackoverflow
  • 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.

    Dead account : +1. Good idea. If a dictionary has 50,000 words in it, two words would cover your number space.
    Mark : @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 :)
  • 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)

    dommer : I think your encoding routine needs to be changed to have: response = acceptedChar[yourNumber % acceptedChar.Length] + response;
  • This project looks like what you're after:

    Base 36 type for .NET (C#)

    Richard : Would suggest base 33, to avoid 5 vs S, 0 vs O and 1 vs I confusions.
  • Here is one implementation of zBase32 encoding on .NET platform (written in C#).

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

0 comments:

Post a Comment