-
Notifications
You must be signed in to change notification settings - Fork 2
PassphraseRegex: building passphrase validation patterns
The PassphraseRegex
class helps construct patterns for passphrase validation. Using a fluent API, a variety of common rules can be applied to produce a pattern that can be used to validate input. The regex produced is generic enough that it can be used on the back-end, or on the front-end via JavaScript.
Good question! Password length strengthens passwords more than some complex criteria. Check out the explanation of the XKCD Password Strength comic to get a better idea.
The patterns produced make use of look-aheads, which are supported since JavaScript 1.5, and thus is compatible with modern browsers. That said, people using this library to validate input could make use of a service call that generates the pattern, then apply it dynamically, but that's probably not ideal. Realistically, once the pattern is determined, you could have it passed down when the page is generated, or add it to your JavaScript file (either manually or via some server side JavaScript object assignment).
The demo page shows some example usages along with the ability to exercise some validation patterns.
Similar examples have been added in later sections.
By default all generated patterns reject leading and trailing whitespace.
Initialization is achieved via either of the following 3 properties so that you're free to construct the builder with code that flows nicely with the first method you decided to use:
-
That
: e.g. PassphraseRegex.That.IncludesRange(...) -
Which
: e.g. PassphraseRegex.Which.ExcludesCharacters(...) -
With
: e.g. PassphraseRegex.With.MinLength(...)
-
MinLength(int length)
: specify the minimum input length (must be >= number of rules used) -
MaxLength(int length)
: specify the maximum input length (must be >= number of rules used) -
IncludesText(string text)
: require the specified text to exist in the input for it to be considered valid (note: partial matches are used; see examples for clarification) -
ExcludesText(string text)
: disallow the specified text from existing in the input for it to be valid -
IncludesAnyCharacters(string characters)
: require any (i.e., at least one) of the characters in the string to exist for the input to be valid -
ExcludesCharacters(string characters)
: disallow any of the characters in the string for the input to be valid -
IncludesRange(char start, char end)
: require any of the characters in the given range, e.g., a-z -
IncludesRange(int start, int end)
: same as above; overload to accept integers -
ExcludesRange(char start, char end)
: disallow any of the characters in the given range, e.g., 0-9 -
ExcludesRange(int start, int end)
: same as above; overload to accept integers -
MaxConsecutiveIdenticalCharacterOf(int length)
: prevents n identical characters, e.g., a max of 2 would make "aaabc" an invalid match -
WithMinimumOccurrenceOf(int length)
: this method is available for some of the positive rules only (i.e.,IncludesAnyCharacters
andIncludesRange
) and specifies the minimum number of characters needed for the input to match -
Options(RegexOptions options)
: accepts RegexOptions (useful to ignore case, compile, etc.) -
ToRegex()
: generates the regex pattern based on the specified rules and returns a PassphraseRegexResult class
Certain methods will throw an exception when given invalid inputs.
-
IncludesText
: throwsArgumentException
when input is null or empty -
ExcludesText
: same asIncludesText
-
IncludesAnyCharacters
: throwsArgumentException
when input is null or empty -
ExcludesCharacters
: same behavior asIncludesAnyCharacters
-
IncludesRange
(int overload): throwsArgumentOutOfRangeException
when inputs are less than 0 or greater than 9. -
ExcludesRange
(int overload): same asIncludesRange
-
WithMinimumOccurrenceOf
: throwsArgumentOutOfRangeException
when the length is less than 1 -
MaxConsecutiveIdenticalCharacterOf
: throwsArgumentOutOfRangeException
when the length is less than 2 -
ToRegex
: throwsArgumentException
if either of the specified min/max lengths are less than the number of rules specified
Once you've specified the PasspphraseRegex
rules and call ToRegex()
, a PassphraseRegexResult
will be returned with the following properties:
-
IsValid
: indicates whether the pattern was successfully generated or not -
Error
: if the pattern was invalid, this contains the Regex class' exception message -
Pattern
: the generated pattern to use with the Regex class -
Regex
: a ready to useRegex
class with the generated pattern (null whenToRegex
fails)
The following code generates a pattern to enforce a password of 8-25 characters that requires at least two lowercase letters in the range of a-z
and numbers excluding those in the range of 0-4
(i.e., numbers in the 5-9
range are acceptable).
var builder = PassphraseRegex.With.MinLength(8)
.MaxLength(25)
.IncludesRange('a', 'z')
.WithMinimumOccurrenceOf(2)
.ExcludesRange(0, 4);
PassphraseRegexResult result = builder.ToRegex();
if (result.IsValid)
{
if (result.Regex.IsMatch(input))
// passphrase meets requirements
else
// passphrase is no good
}
else
{
// check the regex parse exception message for the generated pattern
Console.WriteLine(result.Error);
}
Accept input that contains any of the specified characters (a, b, c, 1, 2, 3).
- Valid: a, 1, f3
- Invalid: x, z6, 9
Code:
PassphraseRegex.That.IncludesAnyCharacters("abc123")
.ToRegex();
Accept input of length 2-6 that contains any of the characters in the range a-z.
- Valid: ab, abc123, xyz
- Invalid: a (too short), AB (case sensitive), 12, !@#, abcdefg (too long)
Code:
PassphraseRegex.With.MinLength(2)
.MaxLength(6)
.IncludesRange('a', 'z')
.ToRegex();
Accept input that contains at least 2 occurrences of characters in the 0-9
range and excludes the characters !
, @
, #
, and characters in the a-z
range. The minimum length is set to 3 based on the number of rules specified, which are the Include/Exclude methods (WithMinimumOccurrenceOf
isn't counted as a rule since it's a constraint applied to the IncludesRange
rule).
- Valid: 123, 8 % $9-4, A4 B5 (case sensitive)
- Invalid: 0 (too short), ABC0 (minimum digit occurrence not met), a1b2, 123#
Code:
PassphraseRegex.Which.ExcludesRange('a', 'z')
.ExcludesCharacters("!@#")
.IncludesRange(0, 9)
.WithMinimumOccurrenceOf(2)
.ToRegex();
Accept input that contains characters in the a-z
and 0-9
ranges, with a maximum length of 8 characters, and a maximum of 3 consecutive identical characters. The minimum length is set to 2 based on the number of rules specified, which are the two Include
methods (the Max*
methods below aren't counted as rules).
- Valid: a1, abc123, aaa1a (4 'a' characters total, but not more than 3 of them are consecutive)
- Invalid: abcd12345 (too long), aaaa1 (exceeds max of 3 consecutive identical character constraint), abc (doesn't include any 0-9 characters)
Code:
PassphraseRegex.With.MaxLength(8)
.IncludesRange('a', 'z')
.IncludesRange('0', '9')
.MaxConsecutiveIdenticalCharacterOf(3)
.ToRegex();