Friday, April 16, 2021

Create a Random Password Generator with C#

Here is our code to read. 
using System;
using System.Text.RegularExpressions;
using System.Text;
                    
public class Program
{
    public static void Main()
    {
	const int MAXIMUM_PASSWORD_ATTEMPTS = 10000;
        bool includeLowercase = true;
        bool includeUppercase = true;
        bool includeNumeric = true;
		bool includeSpecial = false;
        int lengthOfPassword  = 16;
        
		PasswordGeneratorSettings settings = new PasswordGeneratorSettings(includeLowercase, includeUppercase, includeNumeric, includeSpecial, lengthOfPassword);
		string password;
		if (!settings.IsValidLength())
		{
			password = settings.LengthErrorMessage();
		}
		else
		{
			int passwordAttempts = 0;
			do
			{
				password = PasswordGenerator.GeneratePassword(settings);
				passwordAttempts++;
			}
			while (passwordAttempts < MAXIMUM_PASSWORD_ATTEMPTS && !PasswordGenerator.PasswordIsValid(settings, password));
			
			password = PasswordGenerator.PasswordIsValid(settings, password) ? password : "Try again";
		}
        
        Console.WriteLine(password);
    }
}

public class PasswordGeneratorSettings
{
	const string LOWERCASE_CHARACTERS = "abcdefghijklmnopqrstuvwxyz";
	const string UPPERCASE_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	const string NUMERIC_CHARACTERS = "0123456789";
	const string SPECIAL_CHARACTERS = @"!#$%&*@\";
	const int PASSWORD_LENGTH_MIN = 8;
	const int PASSWORD_LENGTH_MAX = 128;
	
	public bool IncludeLowercase {get; set; }
	public bool IncludeUppercase { get; set; }
	public bool IncludeNumbers { get; set; }
	public bool IncludeSpecial { get; set; }
	public int PasswordLength { get; set; }
	public string CharacterSet { get; set; }
	public int MaximumAttempts { get; set; }
	
	public PasswordGeneratorSettings(bool includeLowercase, bool includeUppercase, bool includeNumbers, bool includeSpecial, int passwordLength)
	{
		IncludeLowercase = includeLowercase;
		IncludeUppercase = includeUppercase;
		IncludeNumbers = includeNumbers;
		IncludeSpecial = includeSpecial;
		PasswordLength = passwordLength;
		
		StringBuilder characterSet = new StringBuilder();
		
		if (includeLowercase)
		{
			characterSet.Append(LOWERCASE_CHARACTERS);
		}
		
		if (includeUppercase)
		{
			characterSet.Append(UPPERCASE_CHARACTERS);
		}
		
		if (includeNumbers)
		{
			characterSet.Append(NUMERIC_CHARACTERS);
		}
		
		if (includeSpecial)
		{
			characterSet.Append(SPECIAL_CHARACTERS);
		}
		
		CharacterSet = characterSet.ToString();
	}
	
	public bool IsValidLength()
	{
		return PasswordLength >= PASSWORD_LENGTH_MIN && PasswordLength <= PASSWORD_LENGTH_MAX;
	}
	
	public string LengthErrorMessage()
	{
		return string.Format("Password length must be between {0} and {1} characters", PASSWORD_LENGTH_MIN, PASSWORD_LENGTH_MAX);
	}
}


public static class PasswordGenerator
{
	
	/// <summary>
	/// Generates a random password based on the rules passed in the settings parameter
	/// </summary>
	/// <param name="settings">Password generator settings object</param>
	/// <returns>Password or try again</returns>
	public static string GeneratePassword(PasswordGeneratorSettings settings)
	{
		const int MAXIMUM_IDENTICAL_CONSECUTIVE_CHARS = 2;
		char[] password = new char[settings.PasswordLength];
		int characterSetLength = settings.CharacterSet.Length;
		
		System.Random random = new System.Random();
		for (int characterPosition = 0; characterPosition < settings.PasswordLength; characterPosition++)
		{
			password[characterPosition] = settings.CharacterSet[random.Next(characterSetLength - 1)];
			
			bool moreThanTwoIdenticalInARow =
				characterPosition > MAXIMUM_IDENTICAL_CONSECUTIVE_CHARS
				&& password[characterPosition] == password[characterPosition - 1]
				&& password[characterPosition - 1] == password[characterPosition - 2];
			
			if (moreThanTwoIdenticalInARow)
			{
				characterPosition--;
			}
		}
		
		return string.Join(null, password);
	}
	
	
	/// <summary>
	/// When you give it a password and some settings, it validates the password against the settings.
	/// </summary>
	/// <param name="settings">Password settings</param>
	/// <param name="password">Password to test</param>
	/// <returns>True or False to say if the password is valid or not</returns>
	public static bool PasswordIsValid(PasswordGeneratorSettings settings, string password)
	{
		const string REGEX_LOWERCASE = @"[a-z]";
		const string REGEX_UPPERCASE = @"[A-Z]";
		const string REGEX_NUMERIC = @"[\d]";
		const string REGEX_SPECIAL = @"([!#$%&*@\\])+";
		
		bool lowerCaseIsValid = !settings.IncludeLowercase || (settings.IncludeLowercase && Regex.IsMatch(password, REGEX_LOWERCASE));
		bool upperCaseIsValid = !settings.IncludeUppercase || (settings.IncludeUppercase && Regex.IsMatch(password, REGEX_UPPERCASE));
		bool numericIsValid = !settings.IncludeNumbers || (settings.IncludeNumbers && Regex.IsMatch(password, REGEX_NUMERIC));
		bool symbolsAreValid = !settings.IncludeSpecial || (settings.IncludeSpecial && Regex.IsMatch(password, REGEX_SPECIAL));
		
		return lowerCaseIsValid && upperCaseIsValid && numericIsValid && symbolsAreValid;
	}
}

No comments:

Post a Comment

Server Error in '/' Application when activating "Nintex Forms" web app feature.

Apparently "INSTALL-NFService" need to be run in SharePoint PowerShell to fix this problem.   When I installed Nintex Forms agai...