Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2014-03

Checking characters in a string

12 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

silvioprog
to Richard Mace

2014-03-12 10:53 GMT-03:00 Richard Mace :

Show quoted text 5 lines
Hi, I am trying to check to make sure the a string contains at least 1 uppercase character, 1 lowercase character and 1 number. Any ideas as of the best way of coding this?

In a function, create three Boolean variables (eg. VContainsUpperCase, VContainsLowerCase, VContainsNumber), make a loop through the string and, the measure that finding the ocurrences, set the respective variable to true. Finally, the result will "Result := VContainsUpperCase and VContainsLowerCase and VContainsNumber".

You can also do this with a set of enums. The function would return the set itself. If you are interested, I can explain how it would be with the set too.

Silvio Cl?cio My public projects - github.com/silvioprog -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20140312/f88232cc/attachment.html>

Reply by email

Michael Schnell
to Richard Mace: I am trying to check to make sure the a string contains at least 1 uppercase character, 1…
Richard Mace wrote
I am trying to check to make sure the a string contains at least 1 uppercase character, 1 lowercase character and 1 number. Any ideas as of the best way of coding this?

When using Unicode (under the hood) this is really difficult, as (AFAIK) there is no decent definition what "Uppercase" is.

At best you do a list of all the characters you want to seek for (i.e. a string for each "character", as in Unicode there is no such thging as a character) and do a "pos()" which each of them.

But even then you can't be sure as in Unicode there are multiple ways to code certain characters and you will only find the coding style you defined.

-Michael
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20140312/51c6cba5/attachment.html>

Reply by email

Reinier Olislagers
to Richard Mace: I am trying to check to make sure the a string contains at least 1 uppercase character, 1…
Richard Mace wrote
I am trying to check to make sure the a string contains at least 1 uppercase character, 1 lowercase character and 1 number. Any ideas as of the best way of coding this?

<SCNR>
1. Just check for minimum length and run John the Ripper against the password hash, and check if it breaks the password in a reasonable amount of time
Slightly more serious:
2. Perhaps there's OS supplied functions that provide this kind of funcationality (e.g. apparently on Windows domain controllers, there is
- haven't really read through this though:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa370661%28v=vs.85%29.aspx)

Reply by email

Richard Mace
to silvioprog: 2014-03-12 10:53 GMT-03:00 Richard Mace : In a function, create three Boolean variables…

OK. Perhaps I could just look for a string with a number in it? Richard

"silvioprog" wrote 29 lines
2014-03-12 10:53 GMT-03:00 Richard Mace : > Hi, > I am trying to check to make sure the a string contains at least 1 > uppercase character, 1 lowercase character and 1 number. > Any ideas as of the best way of coding this? > In a function, create three Boolean variables (eg. VContainsUpperCase, VContainsLowerCase, VContainsNumber), make a loop through the string and, the measure that finding the ocurrences, set the respective variable to true. Finally, the result will "Result := VContainsUpperCase and VContainsLowerCase and VContainsNumber". You can also do this with a set of enums. The function would return the set itself. If you are interested, I can explain how it would be with the set too. -- Silvio Cl?cio My public projects - github.com/silvioprog -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20140312/b9763b7b/attachment.html>

Reply by email

silvioprog
to Richard Mace

2014-03-12 12:23 GMT-03:00 Richard Mace :

OK. Perhaps I could just look for a string with a number in it?

Yes. See some functions that handles strings here:

https://github.com/silvioprog/rutils/blob/master/src/rutils.pas

Silvio Cl?cio My public projects - github.com/silvioprog -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20140312/4c68c56f/attachment.html>

Reply by email

Howard Page-Clark
to Richard Mace: I am trying to check to make sure the a string contains at least 1 uppercase character, 1…
Richard Mace wrote
Hi, I am trying to check to make sure the a string contains at least 1 uppercase character, 1 lowercase character and 1 number. Any ideas as of the best way of coding this?

If you restrict yourself to Latin ansi encoding and 'number' means a numeric digit which does not have to be a whole word, the code is fairly simple since almost no parsing is required. Other cases and encodings require more complex string parsing. For example:

-- code begin --

function Valid(const s: string): boolean;
   function HasLowerUpperNumeric: boolean;
   var
     c: Char;
     lower: boolean=False;
     upper: boolean=False;
     numeric: boolean=False;
   begin
     Result:=False;
     for c in s do begin
       if c in ['a'..'z'] then
         lower:=True
       else if c in ['A'..'Z'] then
         upper:=True
       else if c in ['0'..'9'] then
         numeric:=True;
       if lower and upper and numeric then
         Exit(True);
     end;
   end;
begin
   if Length(s) < 3 then
     Exit(False);
   Result:=HasLowerUpperNumeric;
end;

-- code end ---

Reply by email

silvioprog
to Howard Page-Clark

2014-03-12 13:35 GMT-03:00 Howard Page-Clark :

If you restrict yourself to Latin ansi encoding and 'number' means a numeric digit which does not have to be a whole word, the code is fairly simple since almost no parsing is required. Other cases and encodings require more complex string parsing. For example:

It is not hard to allow chars like "?", "?", "?", "?", "?", "?", "?", "?" etc. I left the function a little faster too:

// old
function Valid(const s: string): boolean;
  function HasLowerUpperNumeric: boolean;
  var
    c: char;
    lower: boolean = False;
    upper: boolean = False;
    numeric: boolean = False;
  begin
    Result := False;
    for c in s do
    begin
      if c in ['a'..'z'] then
        lower := True
      else if c in ['A'..'Z'] then
        upper := True
      else if c in ['0'..'9'] then
        numeric := True;
      if lower and upper and numeric then
        Exit(True);
    end;
  end;
begin
  if Length(s) < 3 then
    Exit(False);
  Result := HasLowerUpperNumeric;
end;
// new
function ValidPassword(const S: string): Boolean;
var
  P: PChar;
  F: Boolean;
  L: Boolean = False;
  U: Boolean = False;
  N: Boolean = False;
begin
  P := PChar(S);
  while P^  #0 do
  begin
    case P^ of
      #48..#57: N := True;
      #65..#90: U := True;
      #97..#122: L := True;
    else
      F := P^ = #195;
      if F then
        case P[1] of
          #128..#159: U := True;
          #160..#191: L := True;
        end;
    end;
    Inc(P);
  end;
  Result := L and U and N;
end;

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
const
  c = 20000000;
var
  i: integer;
  b, e: TDateTime;
  s: string = '??1';
  x: Boolean;
begin
  // test Valid efficiency/performance
  b := now;
  for i := 0 to c do
  begin
    x := False;
    x := Valid(s);
  end;
  e := now;
  Edit1.Text := 'Valid: ' + BoolToStr(x, True) + ' - ' +
formatdatetime('hh:nn:ss:zzz', b - e);
  // test ValidPassword efficiency/performance
  b := now;
  for i := 0 to c do
  begin
    x := False;
    x := ValidPassword(s);
  end;
  e := now;
  Edit1.Text := Edit1.Text + ' / ValidPassword: ' + BoolToStr(x, True) + '
- ' + formatdatetime('hh:nn:ss:zzz', b - e);
end;

Result: Valid: *False* - 00:00:00:*861* / ValidPassword: *True* - 00:00:00: *559*

Sure, it's a function that did just for explain, then it can be easily improved.

Silvio Cl?cio My public projects - github.com/silvioprog -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20140312/5a01cf59/attachment.html>

Reply by email

silvioprog
to silvioprog

Oops...

2014-03-12 15:08 GMT-03:00 silvioprog :
[...]

Show quoted text 29 lines
// new function ValidPassword(const S: string): Boolean; var P: PChar; F: Boolean; L: Boolean = False; U: Boolean = False; N: Boolean = False; begin P := PChar(S); while P^ #0 do begin case P^ of #48..#57: N := True; #65..#90: U := True; #97..#122: L := True; else F := P^ = #195; if F then case P[1] of #128..#159: U := True; #160..#191: L := True; end; end; Inc(P); end; Result := L and U and N; end;

Correct function is:

function ValidPassword(const S: string): Boolean;
var
  P: PChar;
  L: Boolean = False;
  U: Boolean = False;
  N: Boolean = False;
begin
  P := PChar(S);
  while P^  #0 do
  begin
    case P^ of
      #48..#57: N := True;
      #65..#90: U := True;
      #97..#122: L := True;
    else
      if P^ = #195 then
        case P[1] of
          #128..#159: U := True;
          #160..#191: L := True;
        end;
    end;
    Inc(P);
  end;
  Result := L and U and N;
end;
Silvio Cl?cio My public projects - github.com/silvioprog -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20140312/02ed1775/attachment.html>

Reply by email

Lukasz Sokol
to Michael Schnell
Michael Schnell wrote 10 lines
On 03/12/2014 07:08 PM, silvioprog wrote: > > It is not hard to allow chars like "?", "?", "?", "?", "?", "?", "?", "?" etc. I left the function a little faster too: > ???? These beasts in UTF-8 are not "char" s (but multi-Byte codes) so your example code "c: char" ... will not work :-( . -Michael

He converts to PChar, then checks byte values, not characters. (see the second message where he rectifies it a bit).

-L.

Reply by email

Richard Mace
to Howard Page-Clark: If you restrict yourself to Latin ansi encoding and 'number' means a numeric digit which…

Thanks Howard,
Your code worked exactly as I expected.

Richard

Howard Page-Clark wrote 53 lines
On 12/03/2014 13:53, Richard Mace wrote: > Hi, > I am trying to check to make sure the a string contains at least 1 > uppercase character, 1 lowercase character and 1 number. > Any ideas as of the best way of coding this? > If you restrict yourself to Latin ansi encoding and 'number' means a numeric digit which does not have to be a whole word, the code is fairly simple since almost no parsing is required. Other cases and encodings require more complex string parsing. For example: -- code begin -- function Valid(const s: string): boolean; function HasLowerUpperNumeric: boolean; var c: Char; lower: boolean=False; upper: boolean=False; numeric: boolean=False; begin Result:=False; for c in s do begin if c in ['a'..'z'] then lower:=True else if c in ['A'..'Z'] then upper:=True else if c in ['0'..'9'] then numeric:=True; if lower and upper and numeric then Exit(True); end; end; begin if Length(s) < 3 then Exit(False); Result:=HasLowerUpperNumeric; end; -- code end --- -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20140318/96eeb50e/attachment.html>

Reply by email