K Singh
K Singh

Reputation: 1730

Custom Base32 encoding code C#

I am have written the following code below to encode a bitarray into custom base32 encoding string. My idea is user can mix the order of base32 array as per requirement and can add similar looking characters like I and 1 etc.

My intention of asking the question is: Is the code written in an appropriate manner or it lacks some basics. As far as i know it is generating the output as per the requirment, however i want to just validate the code here. If there are flaws do let me know.

A user will have a string which needs to be base32 encoded. So in his function he would call it this way.

BitArray ba = new BitArray(Encoding.UTF8.GetBytes(CustomString));
GenerateBase32FromString(ba);

Now the GenerateBase32FromString is as below

static string GenerateStringFromKey(BitArray ba)
{
    try
    {
        // user will modify the order as per requirement.
        char[] cProdKeyPoss = "ABGCD1EF2HI3KL4MN5PQ6RS7TV8WX9YZ".ToCharArray();
        StringBuilder finalstring = new StringBuilder();
        // add zero value bits to round off to multiple of 5
        //ba.Length = ba.Length + (5-(ba.Length % 5));
        // remove bits to round off to multiple of 5
        ba.Length = ba.Length - (ba.Length % 5);
        Console.WriteLine("ba.length = " + ba.Length.ToString());

        for (int i = 0; i < ba.Length; i = i + 5)
        {
            int[] bitvalue = { 0, 0, 0, 0, 0 };

            if (ba.Get(i) == true)
                bitvalue[0] = 1;

            if (ba.Get(i + 1) == true)
                bitvalue[1] = 1;

            if (ba.Get(i + 2) == true)
                bitvalue[2] = 1;

            if (ba.Get(i + 3) == true)
                bitvalue[3] = 1;

            if (ba.Get(i + 4) == true)
                bitvalue[4] = 1;

            int temp = (16 * bitvalue[0]) + (8 * bitvalue[1]) + (4 * bitvalue[2]) + (2 * bitvalue[3]) + (bitvalue[4]);
            finalstring.Append(cProdKeyPoss[temp].ToString());
        }
        Console.WriteLine(finalstring.ToString());
        return finalstring.ToString();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        return null;
    }
}

I have kept both the options where i will chop the bits to round of to multiple of 5 or will add additional zero value bits to make it multiple of 5.

Upvotes: 0

Views: 5170

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1504092

A few suggestions:

  • You don't have any idea of "padding" - so you can't
  • Pass the key characters in as a parameter to the method. You can have an overload for a "default" one if you want
  • Either give the StringBuilder a capacity to start with, or create a char array of the right length and create the string directly from that
  • Catching Exception is almost always a bad idea, and it certainly is here. Any exception would be due to a bug in this code, so just let it bubble up the stack
  • Comparisons with "true" always look smelly to me, and I personally put if/for/while/etc statement bodies in blocks even for single statements, so I would have

    if (ba.Get(i))
    {
        bitValue[0] = 1;
    }
    
  • There's no real point in having the bit array to start with. Why not just add to a value which starts at 0?

    if (ba.Get(i))
    {
        temp += 16;
    }
    // etc
    
  • Repeated code like that suggests a loop:

    int temp = 0;
    for (int j = 0; j < 5; j++)
    {
        if (ba.Get(i + j))
        {
            // This could just be "1 << j" if you don't mind the
            // results being different to your current code
            temp += 1 << (4 - j);
        }
    }
    
  • Library methods shouldn't write to the console
  • Don't call ToString when you've got the right character - just call Append(char) (or set the value in the result char array).

Upvotes: 2

Related Questions