HiveBrain v1.2.0
Get Started
← Back to all entries
patternphpMinor

Confirm regex for validating password policy

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
policyconfirmvalidatingpasswordforregex

Problem

I have the following password policy:

  • At least 8 characters in length



  • At least one digit



  • At least one special* character



*I consider any character that is not a letter, digit or space to be a special character.

 

I've come up with the following regex for enforcing this policy, and it seems to be working.

^(?=.*?[0-9])(?=.*?[^a-zA-Z0-9 ]).{8,}$


Are there any drawbacks or pitfalls with my regex?

Solution

I find the problem with regular expressions is how hard they are to read, and how quickly they become very complicated.

Instead of using a single regex to check for all your conditions I would define a class for a the password that you can then set a series of simple rules for.

This does use static methods, which is not to everyone's taste.

interface Rule
{

public function check(string $value): bool;
}

class LengthRule implements Rule
{
protected $length;

/**
* LengthRule constructor.
*
* @param $length
*/
public function __construct($length)
{
$this->length = $length;
}

public function check(string $value): bool
{
return mb_strlen($value) >= 8;
}
}

class DigitRule implements Rule
{
public function check(string $value): bool
{
return preg_match('/\d/', $value) === 1;
}
}

class SpecialCharacterRule implements Rule
{
public function check(string $value): bool
{
return preg_match('/[^a-zA-Z\d ]/', $value) === 1;
}
}

class Password
{
/** @var Rules[] */
protected static $rules = [];

protected $value;

/**
* @param string $value
*/
public function __construct(string $value)
{
foreach (static::$rules as $rule) {
if (false === $rule->check($value)) {
throw new InvalidArgumentException("The value doesn't" .
" match all rules.");
}
}

$this->value = $value;
}

/**
* @param Rule $rule
*/
public static function registerRule(Rule $rule)
{
self::$rules[] = $rule;
}

}

Password::registerRule(new LengthRule(8));
Password::registerRule(new DigitRule());
Password::registerRule(new SpecialCharacterRule());

new Password('12343.4654j');

Context

StackExchange Code Review Q#154182, answer score: 2

Revisions (0)

No revisions yet.