Reputation: 75
Looking to implement an end user dialog that requires them to create their own password.
Must be 9 characters long. 1 char must be upper case, 1 must be lowercase, one must be a number, ['0'..'9'] and one must be from a set of 6 predefined ascii chars like so. ['!','#','%','&','*','@'].
Have this completed. and works. However, what I wanted to do to was provide visible verification using the onchange event to change the color of the edit box to green if all requirments where met or RED if not. Valdating for the 9 char length is easy enough however checking the 9 various chars to ensure there is at least 1 upper, 1 lower, 1 number and 1 of the predefined is proving a tad difficult. Can anyone help please? Thank you.
This is the code:
procedure TPasswordForm.edtPassword1Change(Sender: TObject);
begin
if Length(edtPassword1.Text <> 9 then
edtPassword1.Color := clRed
else
edtPassword1.Color := clLime;
end;
Upvotes: 3
Views: 5906
Reputation: 6402
This could be achieved using Regular Expressions
Here is an example with error messages.
uses
System.RegularExpressions;
function ValidatePassword(aPassword: String; var ErrorMessage: String): Boolean;
begin
Result := false;
ErrorMessage := '';
if Length(aPassword) <> 9 then
begin
ErrorMessage := 'Password must be exactly 9 characters long';
exit;
end;
if not TRegEx.IsMatch(aPassword, '[a-z]') then
begin
ErrorMessage := 'At least 1 character in the password must be lowercase';
exit;
end;
if not TRegEx.IsMatch(aPassword, '[A-Z]') then
begin
ErrorMessage := 'At least 1 character in the password must be uppercase';
exit;
end;
if not TRegEx.IsMatch(aPassword, '\d') then
begin
ErrorMessage := 'At least 1 character in the password must be a digit';
exit;
end;
if not TRegEx.IsMatch(aPassword, '[!,#,%,&,*,@]') then
begin
ErrorMessage := 'At least 1 character in the password must be one of the following letters: !,#,%,&,*,@';
exit;
end;
Result := True;
end;
Upvotes: 4
Reputation: 80287
For fixed char sets function might be quite simple. Note that it does not accept non-Latin chars.
function IsPasswordCrazy(const s: AnsiString): Boolean;
const
C_Upcase = 1;
C_Locase = 2;
C_Digit = 4;
C_SpecSym = 8;
C_All = C_Upcase or C_Locase or C_Digit or C_SpecSym;
var
i, keys: integer;
begin
if Length(s) <> 9 then begin
Result := False;
Exit;
end;
keys := 0;
for i := 1 to Length(s) do
case s[i] of
'A'..'Z': keys := keys or C_Upcase;
'a'..'z': keys := keys or C_Locase;
'0'..'9': keys := keys or C_Digit;
'!','#','%','&','*','@': keys := keys or C_SpecSym;
end;
Result := keys = C_All;
end;
Upvotes: 7