Skip to content

Instantly share code, notes, and snippets.

@JerryNixon
Created December 14, 2018 19:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JerryNixon/7cda864a9eb2c11dd3d7ae43dbd07195 to your computer and use it in GitHub Desktop.
Save JerryNixon/7cda864a9eb2c11dd3d7ae43dbd07195 to your computer and use it in GitHub Desktop.
internal class Program
{
private static void Main(string[] args)
{
Test("pass");
Test("password");
Test("Password");
Test("P@ssword");
Test("P@ssw0rd");
Test("P@ssW0rD");
Test("P@ssW0rd");
Console.ReadLine();
}
private static void Test(string value)
{
var result = Password.Evaluate(value);
var pass = result.Pass ? "Valid" : "Invalid";
Console.ForegroundColor = result.Pass ? ConsoleColor.Green : ConsoleColor.Red;
Console.WriteLine($"{value}:{pass}");
Console.ResetColor() ;
foreach (var error in result.Errors)
{
Console.WriteLine(error);
}
}
}
public class Password
{
public class Range
{
public Range(int minimum, int? maximum = null)
{
Minimum = minimum;
Maximum = maximum ?? int.MaxValue;
}
public int Minimum { get; set; }
public int Maximum { get; set; }
public (bool Minimum, bool Maximum) WithinRange(int value, bool inclusive)
{
return inclusive ? (value >= Minimum, value <= Maximum) : (value < Minimum, value > Maximum);
}
}
public static (bool Pass, IEnumerable<string> Errors) Evaluate(string value)
{
var result = InnerEvaluate(value, new Range(8), new Range(1), new Range(2,2), new Range(1), new Range(1), true);
return (!result.SelectMany(x => x).Any(), result.SelectMany(x => x));
}
public static (bool Pass, IEnumerable<string> Errors) Evaluate(string value, Range length, Range lower, Range upper, Range digits, Range others, bool inclusive)
{
var result = InnerEvaluate(value, length, lower, upper, digits, others, inclusive);
return (!result.SelectMany(x => x).Any(), result.SelectMany(x => x));
}
private static IEnumerable<IEnumerable<string>> InnerEvaluate(string text, Range length, Range lower, Range upper, Range digits, Range others, bool inclusive)
{
var characters = text
.Select(x => new
{
Value = x.ToString(),
Upper = char.IsUpper(x),
Lower = char.IsLower(x),
Digit = char.IsDigit(x),
Other = !char.IsUpper(x) & !char.IsLower(x) & !char.IsDigit(x)
});
yield return evaluate(characters.Count(), length, "characters");
yield return evaluate(characters.Count(x => x.Lower), lower, "lower case letters");
yield return evaluate(characters.Count(x => x.Upper), upper, "upper case letters");
yield return evaluate(characters.Count(x => x.Digit), digits, "numeric characters");
yield return evaluate(characters.Count(x => x.Other), others, "special characters");
IEnumerable<string> evaluate(int value, Range range, string error)
{
var (Minimum, Maximum) = range.WithinRange(value, inclusive);
if (!Minimum)
{
var amount = inclusive ? range.Minimum : range.Minimum + 1;
yield return $"Too few {error}. Requires at least {amount}.";
}
if (!Maximum)
{
var amount = inclusive ? range.Maximum : range.Maximum - 1;
yield return $"Too many {error}. Requires no more than {amount}";
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment