There are no comments yet...Kick things off by filling out the form below.
Fully Customizable Random Password Generator
Generating random passwords is a common scenario for many applications. The most famous case for this scenario is when the user of a site forgets his or her password and requests for a solution. In my opinion and for some logical reasons resetting the password and sending it to the user's email is the most secure solution.
There are several classes and components written by community members for this purpose and many of them are great enough to be applied to a new project.
While working on a project I faced with this case to generate passwords for users. As security is one of my big concerns in any application and especially in this new application, I decided to invest the wheel for the Nth time and write my own implementation for a fully customizable password generator class. Thank to my search engine rank this may be used more than many other classes out there!
Before talking about the implementation it's worthwhile to talk about the algorithm for everyone who wants to read the code and understand it.
When creating a password we use four kinds of characters: lower case, upper case, numeric and special characters. A user may or may not want one of these types.
A fully customizable password generator needs to be able to get the length of the password and the minimum number of any of these character types in the password.
My approach is to get four parameters (as properties) as the minimum number of these character types in a password as well as the length of the password and a value specifying the user's preference to use one of the four character types to fill the rest of the password with.
Having this background, take a look at the full source code of my password generator class below and follow the post for description.
using System;
using System.Collections.Generic;
namespace PasswordGenerator
{
public class Generator
{
#region Properties and Fields
public int MinUpperCaseChars { get; set; }
public int MinLowerCaseChars { get; set; }
public int MinNumericChars { get; set; }
public int MinSpecialChars { get; set; }
public CharType FillRest { get; set; }
#endregion
#region Public Methods
public string GeneratePassword(int length)
{
int sum = this.MinUpperCaseChars + this.MinLowerCaseChars +
this.MinNumericChars + this.MinSpecialChars;
if (length < sum)
throw new ArgumentException("length parameter must be valid!");
List<char> chars = new List<char>();
if (this.MinUpperCaseChars > 0)
{
chars.AddRange(GetUpperCasePasswordChars(this.MinUpperCaseChars));
}
if (this.MinLowerCaseChars > 0)
{
chars.AddRange(GetLowerCasePasswordChars(this.MinLowerCaseChars));
}
if (this.MinNumericChars > 0)
{
chars.AddRange(GetNumericPasswordChars(this.MinNumericChars));
}
if (this.MinSpecialChars > 0)
{
chars.AddRange(GetSpecialPasswordChars(this.MinSpecialChars));
}
int restLength = length - chars.Count;
switch (this.FillRest)
{
case (CharType.UpperCase):
chars.AddRange(GetUpperCasePasswordChars(restLength));
break;
case (CharType.LowerCase):
chars.AddRange(GetLowerCasePasswordChars(restLength));
break;
case CharType.Numeric:
chars.AddRange(GetNumericPasswordChars(restLength));
break;
case CharType.Special:
chars.AddRange(GetSpecialPasswordChars(restLength));
break;
default:
chars.AddRange(GetLowerCasePasswordChars(restLength));
break;
}
return GeneratePasswordFromList(chars);
}
#endregion
#region Private Methods
private List<char> GetUpperCasePasswordChars(int count)
{
List<char> result = new List<char>();
Random random = new Random();
for (int index = 0; index < count; index++)
{
result.Add(Char.ToUpper(Convert.ToChar(random.Next(65, 90))));
}
return result;
}
private List<char> GetLowerCasePasswordChars(int count)
{
List<char> result = new List<char>();
Random random = new Random();
for (int index = 0; index < count; index++)
{
result.Add(Char.ToLower(Convert.ToChar(random.Next(97, 122))));
}
return result;
}
private List<char> GetNumericPasswordChars(int count)
{
List<char> result = new List<char>();
Random random = new Random();
for (int index = 0; index < count; index++)
{
result.Add(Convert.ToChar(random.Next(0, 9).ToString()));
}
return result;
}
private List<char> GetSpecialPasswordChars(int count)
{
List<char> result = new List<char>();
Random random = new Random();
for (int index = 0; index < count; index++)
{
result.Add(Char.ToLower(Convert.ToChar(random.Next(35, 38))));
}
return result;
}
private string GeneratePasswordFromList(List<char> chars)
{
string result = string.Empty;
Random random = new Random();
while (chars.Count > 0)
{
int randomIndex = random.Next(0, chars.Count);
result += chars[randomIndex];
chars.RemoveAt(randomIndex);
}
return result;
}
#endregion
}
}
When generating the password, first I create a list of characters that will be generated to be used in the password then add characters to this list from other methods that generate specified number of different types of characters randomly.
In each of the four methods that generate a list of characters I use random numbers to generate a character in a loop. When I want a character, I use the code of the character to generate it and when I want a number, I simply use the generated number as is.
After filling the list with the minimum number of characters requested by user, I check for the user's preference for the rest of the list (if there is any space remained) then generate characters for this space.
The last step is to generate the password string from the list of generated characters. In a loop I generate random integers for the index of my list and add that item to the string and remove it from the list. After finishing the loop I have an empty list and a generated string that is my final result.
The code shown below, guides you on using this class. Note that if you set the integer properties with a natural number (larger than zero) then it will be used otherwise,this generator doesn't use characters for that type. Everything has a default value so you don't need to worry about anything except passing a valid integer as parameter to GeneratePassword method.
[TestMethod()]
public void GeneratePasswordTest()
{
Generator target = new Generator();
int length = 10;
target.MinLowerCaseChars = 2;
target.MinUpperCaseChars = 1;
target.MinNumericChars = 3;
target.MinSpecialChars = 2;
target.FillRest = CharType.LowerCase;
string actual;
actual = target.GeneratePassword(length);
// This is just to see that green color :-D
Assert.IsNotNull(actual);
}
You can download the source code of this class from here.
[advertisement] Axosoft OnTime 2008 is four developer tools in one: bug tracking, project wiki, feature management, and help desk. It manages your development process so developers can focus on coding. Installed or Hosted – Free Single-user license -- Free 30-day team trial.
No Comments : 02.15.08
