tsJensen

A quest for software excellence...

Base 30 Type in C#

I'm experimenting with using the Guid type in databases and applications but I don't like the string format of the Guid. It's not easily read or formatted on a report. I wanted to find a way to represent very large integers such as the Guid (a 128 bit integer under the covers), so I looked around and found a Base 36 type sample on Code Project article by Steve Barker that gave me a great start.

The problem with Base 36 is that several characters are similar to other characters or numbers, so took the code and modified it to use a limited set of 20 characters that are distinctive from numbers and other characters sufficiently to make it easy for humans to read them back or hand enter them in a user interface.

I downloaded the code and went to work making the modifications. Here's the core of the Base 30 struct:

//removed are chars similar to numbers or another char when printed: I, J, O, Q, V, Z
private static List<char> alphaDigits = new List<char>(new char[]{ 'A','B','C','D','E','F','G','H','K','L','M','N','P','R','S','T','U','W','X','Y' });

private static byte Base30DigitToNumber(char Base30Digit)
{
    if(char.IsDigit(Base30Digit))
    {
        //Handles 0 - 9
        return byte.Parse(Base30Digit.ToString());
    }
    else
    {
        //Converts one base-30 digit to it's base-10 value
        if (alphaDigits.IndexOf(Base30Digit) > -1)
        {
            //Handles ABCDEFGHKLMNPRSTUWXY  (these are letters that cannot be confused for numbers)
            int index = alphaDigits.IndexOf(Base30Digit) + 10;
            return (byte)(index);
        }
        else
        {
            throw new InvalidBase30DigitException(Base30Digit);
        }
    }
}

private static char NumberToBase30Digit(byte NumericValue)
{
    //Converts a number to it's base-30 value.
    //Only works for numbers <= 29.
    if(NumericValue > 29)
    {
        throw new InvalidBase30DigitValueException(NumericValue);
    }

    //Numbers:
    if(NumericValue < 10)
    {
        return NumericValue.ToString()[0];
    }
    else
    {
        //Note that A is code 65, and in this
        //scheme, A = 10, Y = 29 ABCDEFGHKLMNPRSTUWXY  use alphaDigits for List<char>
        int index = NumericValue - 10;
        return alphaDigits[index]; //(char)(NumericValue + 55);
    }
}

Now, I have added a couple of static methods to give me a shiny Base 30 guid string and convert that string back to a Guid here:

/// <summary>
/// Convert a Guid to a set of four Base30 string values connected by a dash character.
/// </summary>
/// <param name="g"></param>
/// <returns></returns>
public static string GuidToBase30Set(Guid g)
{
    byte[] b = g.ToByteArray();
    Base30 b1 = BitConverter.ToUInt32(b, 0);
    Base30 b2 = BitConverter.ToUInt32(b, 4);
    Base30 b3 = BitConverter.ToUInt32(b, 8);
    Base30 b4 = BitConverter.ToUInt32(b, 12);
    return string.Format("{0}-{1}-{2}-{3}", b1, b2, b3, b4);
}

/// <summary>
/// Convert the Base30 set string produced by GuidToBase30Set back to a Guid.
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static Guid Base30SetToGuid(string s)
{
    string[] p = s.Split('-');
    if (p.Length != 4) throw new ArgumentException("Invalid Base30Set format.");
    try
    {
        Base30 b1 = p[0];
        Base30 b2 = p[1];
        Base30 b3 = p[2];
        Base30 b4 = p[3];

        uint x1 = (uint)b1.NumericValue;
        uint x2 = (uint)b2.NumericValue;
        uint x3 = (uint)b3.NumericValue;
        uint x4 = (uint)b4.NumericValue;

        byte[] a1 = BitConverter.GetBytes(x1);
        byte[] a2 = BitConverter.GetBytes(x2);
        byte[] a3 = BitConverter.GetBytes(x3);
        byte[] a4 = BitConverter.GetBytes(x4);

        byte[] gb = new byte[16];

        a1.CopyTo(gb, 0);
        a2.CopyTo(gb, 4);
        a3.CopyTo(gb, 8);
        a4.CopyTo(gb, 12);

        return new Guid(gb);
    }
    catch
    {
        throw new ArgumentOutOfRangeException("Invalid Base30Set string.");
    }
}

The code above gets you something like this:

Common Guid string: b908d243-c1ac-4ea4-a954-121e4ab5c334
Base30Set from same: 47PGC95-1S8WCHP-MPTTA1-16CUN8P

You can download the code here (Base30.zip 3.6 KB).

Apple, I'm a PC and You're a Hypocrite

One of the latest Apple ads makes fun of Microsoft for spending more on marketing than on fixing Vista. Time for all you fruit computer junkies to face some cold hard facts:

Let's take our most recent SEC filing quarter for both companies and compare spending on sales, marketing and administration versus research and development and then average that spending per employee.

Microsoft spends about $25,000 per employee on R&D and $43,000 on sales, marketing and administration.
A ratio of 1 to 1.72.

Apple spends about $16,300 per employee on R&D and $51,200 on sales, marketing and administration.
A ratio of 1 to 3.13.

So relatively speaking, Apple spends nearly twice as much on sales, marketing and administration as Microsoft does.

And that's one reason why I'm a PC. You can keep your fruit computer.

What is Enterprise Software Architecture

I just posted this on a linkedin group to which I belong, but I thought I'd also like to pose the question here.

I'd like to get a discussion started that attempts to define enterprise software architecture. My own definition seems to be evolvoing with every enterprise for whom I've worked. In the abstract, for me, enterprise software architure is the art of putting the pieces of multiple puzzles together into one great work of art.

There are many puzzles to choose from and every enterprise has a unique mix. There are multiple teams with various skillsets and experience. There are multiple business processes sometimes with unique and strange business rules. Technology platforms that differ, communications protocols that won't communicate with one another, languages, frameworks, compilers, IDEs, components, and hardware that vary from team to team and department to department. Ours is the task of taking these disparate and often incongruous pieces and molding them into one coherent masterpiece of technology and human resources to get more done, get it done better, quicker, cheaper and easier. And if we do our jobs well, it may be that no one will notice that we did it at all.

What do you think?