asp.net 生成随机密码的具体代码
程序员文章站
2024-03-01 09:41:04
复制代码 代码如下:public static class randompassword { &nbs...
复制代码 代码如下:
public static class randompassword
{
// define default min and max password lengths.
private static int default_min_password_length = 8;
private static int default_max_password_length = 10;
// define supported password characters divided into groups.
private static string password_chars_lcase = "abcdefgijkmnopqrstwxyz";
private static string password_chars_ucase = "abcdefghjklmnpqrstwxyz";
private static string password_chars_numeric = "23456789";
private static string password_chars_special = "*$-+?_&=!%{}/";
/// <summary>
/// generates a random password.
/// </summary>
/// <returns>
/// randomly generated password.
/// </returns>
/// <remarks>
/// the length of the generated password will be determined at
/// random. it will be no shorter than the minimum default and
/// no longer than maximum default.
/// </remarks>
public static string generate()
{
return generate(default_min_password_length,
default_max_password_length);
}
/// <summary>
/// generates a random password of the exact length.
/// </summary>
/// <param name="length">
/// exact password length.
/// </param>
/// <returns>
/// randomly generated password.
/// </returns>
public static string generate(int length)
{
return generate(length, length);
}
/// <summary>
/// generates a random password.
/// </summary>
/// <param name="minlength">
/// minimum password length.
/// </param>
/// <param name="maxlength">
/// maximum password length.
/// </param>
/// <returns>
/// randomly generated password.
/// </returns>
/// <remarks>
/// the length of the generated password will be determined at
/// random and it will fall with the range determined by the
/// function parameters.
/// </remarks>
public static string generate(int minlength,
int maxlength)
{
// make sure that input parameters are valid.
if (minlength <= 0 || maxlength <= 0 || minlength > maxlength)
return null;
// create a local array containing supported password characters
// grouped by types. you can remove character groups from this
// array, but doing so will weaken the password strength.
char[][] chargroups = new char[][]
{
password_chars_lcase.tochararray(),
password_chars_ucase.tochararray(),
password_chars_numeric.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];
random random = new random(seed);
char[] password = null;
// allocate appropriate memory for the password.
if (minlength < maxlength)
password = new char[random.next(minlength, maxlength + 1)];
else
password = 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 < password.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.
password[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(password);
}
}