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;
/// 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); } }
您可能感興趣的文章:
ASP.NET MVC5網(wǎng)站開發(fā)之添加\刪除\重置密碼\修改密碼\列表瀏覽管理員篇2(六)
ASP.NET MVC5網(wǎng)站開發(fā)用戶修改資料和密碼(六)
asp.net利用cookie保存用戶密碼實現(xiàn)自動登錄的方法
ASP.NET 回發(fā)密碼框清空問題處理方法
解讀ASP.NET密碼強度驗證代碼實例分享
asp.net中使用cookie與md5加密實現(xiàn)記住密碼功能的實現(xiàn)代碼
淺析ASP.NET生成隨機密碼函數(shù)
asp.net membership 密碼重設(shè)
ASP.net中md5加密碼的方法
ASP.NET jQuery 實例13 原創(chuàng)jQuery文本框字符限制插件-TextArea Counter