I created a class designed to validate passwords based on user defined criteria. Each PasswordValidator object objects a minimum and maximum password length, a character blacklist, as well as customizable Uppercase, Lowercase, and digit requirements. I am well aware that I could have used regex but I wanted to avoid using it for extra practice with classes. Here is an example object I created as well as the class.
var passwordValidator = new PasswordValidator
{
MinLength = 6,
MaxLength = 13,
UpperRequirement = 1,
LowerRequirement = 1,
DigitRequirment = 1,
CharBlacklist = new char[] { 'T', '&' }
};
while (true)
{
var input = Console.ReadLine();
if (input == "exit")
{
break;
}
else
{
Console.WriteLine(passwordValidator.CheckPassword(input));
}
}
class PasswordValidator
{
public uint MinLength { get; init; }
public uint MaxLength { get; init; }
public uint UpperRequirement { get; init; }
public uint LowerRequirement { get; init; }
public uint DigitRequirment { get; init; }
public char[]? CharBlacklist { get; init; }
public bool CheckPassword(string password)
{
bool hasBlacklist = CharBlacklist != null;
bool hasMaxLength = MaxLength != 0;
// Length Checking
if (password.Length < MinLength || (hasMaxLength && password.Length > MaxLength))
{
return false;
}
uint upperCount = 0;
uint lowerCount = 0;
uint digitCount = 0;
foreach (char passwordChar in password)
{
if (hasBlacklist && !AllowedChar(passwordChar))
{
return false;
}
if (char.IsUpper(passwordChar))
{
upperCount++;
}
else if (char.IsLower(passwordChar))
{
lowerCount++;
}
else if (char.IsDigit(passwordChar))
{
digitCount++;
}
}
if (upperCount < UpperRequirement || lowerCount < LowerRequirement || digitCount < DigitRequirment)
{
return false;
}
else
{
return true;
}
}
private bool AllowedChar(char passwordChar)
{
foreach (var blacklistChar in CharBlacklist)
{
if (passwordChar == blacklistChar)
{
return false;
}
}
return true;
}
}
All types of feedback are appreciated but here are some questions I have about how I could improve my code.
- My C# knowledge is fairly limited. The language I know the best is Java (0.5 years). Are there any language specific style issues you can see in my code? Did I get carried away with C# language features?
- I chose not to create any constructors for my class in favor of object initializer syntax. I did this because All of the properties in the class are meant to be optional. Did I make the right move?
- One design issue I see is that MinLength could be greater than MaxLength. How would I fix this?
- My CheckPassword method is quite lengthy and contains a lot of if else statements. It also has two special cases where there is no MaxLength and where there is a Character Blacklist. What improvements (if any) should I make to that method.
return ! CharBlacklist.Contains(passwordChar);
\$\endgroup\$