var use any math library to generate a random number from 0 to 26 cubed - 1, then assign the letters based on the value of that random integer...
in the following, the backslash represents integer division, i.e., drop any fractional remainder
first character = ascii(65 + integer modulus 26)
second character = ascii(65 + (integer \ 26) modulus 26
third character = ascii(65 + ((integer \ 26) \ 26) modulus 26
ahh, thx to @Graphain I realize you want to eliminate any chance of picking the same three character combination again... welll then here's a way...
- Create a collection (List?) containing 676 (26*26) 32 bit integers, all initialized to 2^26-1 (so bits 0-25 are all set = 1). Put 26 of these integers into each of 26 inner dictionaries so this becomes an dictionary of 26 dictionaries each of which has 26 of these integers. Label the inner dictionaries A-Z. Within each inner array, label the integers A-Z.
- Randomly pick one of 26 outer arrays (this sets the first character).
- From the array chosen randomly pick one of it's contained inner arrays. This sets the second character.
- Then randomly pick a number from 0 to n, (where n is the count of bits in the integer that are still set to 1)... Which bit in the number determines the last character.
- Set that bit to zero
- If all bits in the integer have been set to zero, remove integer from array
- If this inner array is now empty, (all integers are gone) remove it from outer array.
- Repeat from step 2 until outer array is empty or you get tired...
Here's some sample code (not tested):
public class RandomAlphaTriplet
{
private static readonly Dictionary<char, Dictionary<char, int>> vals =
new Dictionary<char, Dictionary<char, int>>();
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static readonly Random rnd = new Random(DateTime.Now.Millisecond);
private const int initVal = 0x3FFFFFF;
static RandomAlphaTriplet()
{
foreach (var c in chars)
vals.Add(c, chars.ToDictionary(
ic => ic, ic => initVal));
}
public static string FetchNext()
{
var c1 = chars[rnd.Next(vals.Count)];
var inrDict = vals[c1];
var c2 = chars[rnd.Next(inrDict.Count)];
var intVal = inrDict[c2];
var bitNo = rnd.Next(BitCount(intVal));
var bitPos = 0;
while (bitNo > 0)
{
if ((intVal & 0x0001) > 0) bitNo--;
bitPos++;
intVal <<= 1;
}
var c3 = chars[bitPos];
inrDict[c2] &= ~(1 << bitPos);
if (inrDict[c2] == 0) inrDict.Remove(c2);
if (vals[c1].Count == 0) vals.Remove(c1);
return string.Concat(c1, c2, c3);
}
private static int BitCount(int x)
{ return ((x == 0) ? 0 : ((x < 0) ? 1 : 0) + BitCount(x << 1)); }
}