Created
December 14, 2018 19:23
-
-
Save JerryNixon/7cda864a9eb2c11dd3d7ae43dbd07195 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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