To generate an alphanumeric Random code
///
/// Public static function Generate Random Code
/// generate the random code
/// Created By: Munesh
/// Created Date: Feb 10, 2010
///
///
string
public static string GenerateRandomCode()
{
int _minLength = 6, _maxLength = 6;
string _charsLCase = "abcdefgijkmnopqrstwxyz";
string _charsUCase = "ABCDEFGHJKLMNPQRSTWXYZ";
string _charsNumeric = "23456789";
// Create a local array containing supported Verification Code characters
char[][] _charGroups = new char[][]
{
_charsLCase.ToCharArray(),
_charsUCase.ToCharArray(),
_charsNumeric.ToCharArray(),
//PASSWORD_CHARS_SPECIAL.ToCharArray()
};
// Use this array to track the number of unused characters in each
// character group.
int[] _charsLeftInGroup = new int[_charGroups.Length];
// Initially, all characters in each group are not used.
for (int i = 0; i < _charsLeftInGroup.Length; i++)
_charsLeftInGroup[i] = _charGroups[i].Length;
// Use this array to track (iterate through) unused character groups.
int[] _leftGroupsOrder = new int[_charGroups.Length];
// Initially, all character groups are not used.
for (int i = 0; i < _leftGroupsOrder.Length; i++)
_leftGroupsOrder[i] = i;
// Because we cannot use the default randomizer, which is based on the
// current time (it will produce the same "random" number within a
// second), we will use a random number generator to seed the
// randomizer.
// Use a 4-byte array to fill it with random bytes and convert it then
// to an integer value.
byte[] _randomBytes = new byte[4];
// Generate 4 random bytes.
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(_randomBytes);
// Convert 4 bytes into a 32-bit integer value.
int _seed = (_randomBytes[0] & 0x7f) << 24 |
_randomBytes[1] << 16 |
_randomBytes[2] << 8 |
_randomBytes[3];
// Now, this is real randomization.
Random random = new Random(_seed);
// This array will hold password characters.
char[] _verificationCode = null;
// Allocate appropriate memory for the password.
if (_minLength < _maxLength)
_verificationCode = new char[random.Next(_minLength, _maxLength + 1)];
else
_verificationCode = new char[_minLength];
// Index of the next character to be added to password.
int _nextCharIdx;
// Index of the next character group to be processed.
int _nextGroupIdx;
// Index which will be used to track not processed character groups.
int _nextLeftGroupsOrderIdx;
// Index of the last non-processed character in a group.
int _lastCharIdx;
// Index of the last non-processed group.
int _lastLeftGroupsOrderIdx = _leftGroupsOrder.Length - 1;
// Generate password characters one at a time.
for (int i = 0; i < _verificationCode.Length; i++)
{
// If only one character group remained unprocessed, process it;
// otherwise, pick a random character group from the unprocessed
// group list. To allow a special character to appear in the
// first position, increment the second parameter of the Next
// function call by one, i.e. lastLeftGroupsOrderIdx + 1.
if (_lastLeftGroupsOrderIdx == 0)
_nextLeftGroupsOrderIdx = 0;
else
_nextLeftGroupsOrderIdx = random.Next(0,
_lastLeftGroupsOrderIdx);
// Get the actual index of the character group, from which we will
// pick the next character.
_nextGroupIdx = _leftGroupsOrder[_nextLeftGroupsOrderIdx];
// Get the index of the last unprocessed characters in this group.
_lastCharIdx = _charsLeftInGroup[_nextGroupIdx] - 1;
// If only one unprocessed character is left, pick it; otherwise,
// get a random character from the unused character list.
if (_lastCharIdx == 0)
_nextCharIdx = 0;
else
_nextCharIdx = random.Next(0, _lastCharIdx + 1);
// Add this character to the password.
_verificationCode[i] = _charGroups[_nextGroupIdx][_nextCharIdx];
// If we processed the last character in this group, start over.
if (_lastCharIdx == 0)
_charsLeftInGroup[_nextGroupIdx] =
_charGroups[_nextGroupIdx].Length;
// There are more unprocessed characters left.
else
{
// Swap processed character with the last unprocessed character
// so that we don't pick it until we process all characters in
// this group.
if (_lastCharIdx != _nextCharIdx)
{
char _temp = _charGroups[_nextGroupIdx][_lastCharIdx];
_charGroups[_nextGroupIdx][_lastCharIdx] =
_charGroups[_nextGroupIdx][_nextCharIdx];
_charGroups[_nextGroupIdx][_nextCharIdx] = _temp;
}
// Decrement the number of unprocessed characters in
// this group.
_charsLeftInGroup[_nextGroupIdx]--;
}
// If we processed the last group, start all over.
if (_lastLeftGroupsOrderIdx == 0)
_lastLeftGroupsOrderIdx = _leftGroupsOrder.Length - 1;
// There are more unprocessed groups left.
else
{
// Swap processed group with the last unprocessed group
// so that we don't pick it until we process all groups.
if (_lastLeftGroupsOrderIdx != _nextLeftGroupsOrderIdx)
{
int _temp = _leftGroupsOrder[_lastLeftGroupsOrderIdx];
_leftGroupsOrder[_lastLeftGroupsOrderIdx] =
_leftGroupsOrder[_nextLeftGroupsOrderIdx];
_leftGroupsOrder[_nextLeftGroupsOrderIdx] = _temp;
}
// Decrement the number of unprocessed groups.
_lastLeftGroupsOrderIdx--;
}
}
// Convert password characters into a string and return the result.
return new string(_verificationCode);
}