I wrote the following to generate short database identifier names (e.g. parameters). This isn't a terribly practical requirement and could be fulfilled nearly as well by using base-26, but what seemed like a simple problem became an interesting challenge.
My result doesn't feel very clean, and it has some collisions. I would appreciate performance or elegance suggestions.
Rules: First character must be alphabetic, subsequent must be alphanumeric.
public string intToDatabaseIdentifier(int number)
{
if(number < 0 || number > 1000000)
throw new ArgumentOutOfRangeException("number");
if(number > 25 && number <= 25 + 10) // Skip 0-9 (modified base 36)
number += 10;
if(number > 971 && number <= 971 + 360) // Skip 0a-09 (modified base 36)
number += 360;
if(number > 35027 && number <= 35027 + 12960) // Skip 0aa-099 (modified base 36)
number += 12960;
var stack = new Stack<char>();
// Base 36, but starting with letters rather than numbers
const string characters = "abcdefghijklmnopqrstuvwxyz0123456789";
while(number >= 0) {
stack.Push(characters[number % 36]);
number = number / 36 - 1;
}
return new string(stack.ToArray());
}
Additional characters (e.g. _
, #
) can be easily added, but they yield little and make the method less database-agnostic, so I'll stick with alphanumerics.
Results:
a b c d e f g h i j k l m n o p q r s t u v w x y z
aa ab ac ad ae af ag ah ai aj aa ab ac ad ae af ag ah ai aj ak al am an ao
ap aq ar as at au av aw ax ay az a0 a1...
Ideally the output will be as above (without the collisions). The accepted answer in SO works but produces output in an unusual order, e.g. aa ba ca
0
you cannot use? \$\endgroup\$