Recent

Author Topic: Lazarus implementation of a CAPTCHA  (Read 7639 times)

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1153
  • Professional amateur ;-P
Lazarus implementation of a CAPTCHA
« on: September 17, 2021, 10:07:02 pm »
Hi Y'all,

I was fumbling on GitHub, as you do, and found this gem: CAPTCHA Verification for Delphi, made by Jens Borrisholt.

And because I'm always procrastinating on my own projects and I had some free time, I decided to re-write it for Lazarus / Free Pascal.

The repository is here: lazCAPTCHA.

And attached are some screenshot of the example application, one under Ubuntu and another with Wine(Sorry have no access to a windows machine to make a screenshot).

Hope this helps someone in any way :)

Cheers,
Gus
Lazarus 3.99(main) FPC 3.3.1(main) Ubuntu 23.10 64b Dark Theme
Lazarus 3.0.0(stable) FPC 3.2.2(stable) Ubuntu 23.10 64b Dark Theme
http://github.com/gcarreno

Leledumbo

  • Hero Member
  • *****
  • Posts: 8777
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Lazarus implementation of a CAPTCHA
« Reply #1 on: September 19, 2021, 06:20:39 am »
At first I thought you were using some kind of online backend, but actually having this written in offline native Pascal expands the possibilities of practical usage to a different level. Great job!
I think it deserves a place in online package manager.

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1153
  • Professional amateur ;-P
Re: Lazarus implementation of a CAPTCHA
« Reply #2 on: September 19, 2021, 07:45:45 am »
Hey Leledumbo,

At first I thought you were using some kind of online backend, but actually having this written in offline native Pascal expands the possibilities of practical usage to a different level. Great job!

Thank you very much for the compliment, but alas, I can't accept all the credit. I just adapted/copied the work of the original author: Jens Borrisholt.

I think it deserves a place in online package manager.

That's an awesome endorsement!! Thanks!!!

But, IMHO, it needs some modifications/additions before I can consider bugging GetMem for a consideration to be put on OPM:
  • Needs to be a visual component like TImage
  • Needs to allow the user to chose some aspects of the font. The least of it like Serif vs Non Serif.
  • Needs to allow the user to chose case sensitivity
  • Needs to allow the user to choose alpha, numeric or alphanumeric
  • The aspect ratio of the rectangle HAS to be maintained and some MinWidth/MinHeight should be imposed
  • I need to see why if I compile it with optimization bigger than 1 it messes up the font size and rotation

With regards to 1, I'm a crappy component developer. I have no experience with it and I'm the last person to do it.
The original author had it descend from TComponent already, but I downgraded it to descending from TObject because I saw no functionality that would require it to descend from TComponent.
If I'm to continue to expand on the development of this, I'll require some help, or at least some time to look at some examples and then adventure in the realm of true component development.

With regards to 2 to 4, this isn't that hard to implement once I have a grasp of the whole component thing.

With regards to 5, again, not that hard to implement, but I think it's needed to at least have a consistent canvas size to contain a good amount of places to put characters.

With regards to 6: This for me is Voodoo realm and I think I need to report a bug but I'm not completely sure. I've started another thread where I'm discussing it.
My first problem was the background being black when I wanted it white. I finally found out how to do it but then I got an issue with the TBitmap's PixelFormat  property and the place I set it. If I set it after setting the Brush/Pen it pretty much resets those and the background was still black. So the solution is setting that before setting Brush/Pen, but I still don't understand how setting PixelFormat would reset the Brush/Pen setting :(
I'm now in the process of finding out why if the Optimization is not 1, then the rotation and size of the font is not obeyed.

Until I tackle those points, I guess I'll refrain from bugging GetMem for a place on OPM.
And I think I would have to make it a package, which ATM it isn't :)

Cheers,
Gus
Lazarus 3.99(main) FPC 3.3.1(main) Ubuntu 23.10 64b Dark Theme
Lazarus 3.0.0(stable) FPC 3.2.2(stable) Ubuntu 23.10 64b Dark Theme
http://github.com/gcarreno

cappe

  • Full Member
  • ***
  • Posts: 192
Re: Lazarus implementation of a CAPTCHA
« Reply #3 on: September 19, 2021, 09:05:33 am »
sounds interesting, i think i will use it too

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1153
  • Professional amateur ;-P
Re: Lazarus implementation of a CAPTCHA
« Reply #4 on: September 19, 2021, 09:16:09 am »
Hey cappe,

sounds interesting, i think i will use it too

Thanks man, I'll accept all the, ego boosting, love I can get :)

Cheers,
Gus
Lazarus 3.99(main) FPC 3.3.1(main) Ubuntu 23.10 64b Dark Theme
Lazarus 3.0.0(stable) FPC 3.2.2(stable) Ubuntu 23.10 64b Dark Theme
http://github.com/gcarreno

wp

  • Hero Member
  • *****
  • Posts: 12476
Re: Lazarus implementation of a CAPTCHA
« Reply #5 on: September 19, 2021, 07:30:38 pm »
An interesting topic which motivated me to do it myself - see attachment.

My TCaptcha descends from TGraphicControl and contains its own drawing routine --> just place it on the form and use it. There are several properties to define its behaviour:
  • NumChars: Number of characters in the captcha
  • NumLines: Number of lines drawn over the captcha
  • Font1, Font2: two fonts to be mixed within the captcha randomly
  • MaxAngle: maximum rotation angle for the characters which are rotated by a random angle between -MaxAngle and +MaxAngle
  • BackgroundColor: the background color of the area of the control covered by the captcha. Character and line colors are selected such that a minimum brightness difference to the background color is achieved.
  • Options: This is a set of the following options which can be combined:
      - coUppercase: Use uppercase characters
      - coLowercase: Use lowercase characters
      - coNumbers: Use numeric characters 0..9
        (the characters which are hard to distinguish are skipped, zero vs uppercase O, lowercase L vs upper case I
      - coRotated: Characters are rotated
      - coFont1: Font1 is used
      - coFont2: Font2 is used
      - coLines: Lines are drawn over the captcha
« Last Edit: September 19, 2021, 07:35:46 pm by wp »

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Lazarus implementation of a CAPTCHA
« Reply #6 on: September 19, 2021, 08:31:33 pm »
wp, yours is an elegant implementation, and a nice test app, thank you.
It is also a good illustration of intelligent use of indexed properties.
A very minor optimisation of the RotatePoint function would be to define a PiOver180 const the compiler would calculate once at compilation, and use the SinCos() routine from the Math unit which evaluates both needed values together.

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1153
  • Professional amateur ;-P
Re: Lazarus implementation of a CAPTCHA
« Reply #7 on: September 19, 2021, 08:56:29 pm »
Hey WP,

An interesting topic which motivated me to do it myself - see attachment.

Your implementation looks FRIGGIN AWESOME!!!!

I'll have a good look at it and try and learn a ton so I can change my implementation into the component that I wanted to do!!

Can't say this enough: Humongous awesome effort and I'm sure I'm gonna learn tons about making a graphical component!!!

Only one question: Did you stumble upon the optimization above 1 problem?

Cheers,
Gus
Lazarus 3.99(main) FPC 3.3.1(main) Ubuntu 23.10 64b Dark Theme
Lazarus 3.0.0(stable) FPC 3.2.2(stable) Ubuntu 23.10 64b Dark Theme
http://github.com/gcarreno

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1153
  • Professional amateur ;-P
Re: Lazarus implementation of a CAPTCHA
« Reply #8 on: September 19, 2021, 09:51:40 pm »
Hey WP,

Looks like Lazarus <= 2.0.12 doesn't have ColorToHSV.

Is there a way to make it compatible with Lazarus 2.0.12 and below?

Thanks!!

Cheers,
Gus
« Last Edit: September 19, 2021, 09:55:00 pm by Gustavo 'Gus' Carreno »
Lazarus 3.99(main) FPC 3.3.1(main) Ubuntu 23.10 64b Dark Theme
Lazarus 3.0.0(stable) FPC 3.2.2(stable) Ubuntu 23.10 64b Dark Theme
http://github.com/gcarreno

wp

  • Hero Member
  • *****
  • Posts: 12476
Re: Lazarus implementation of a CAPTCHA
« Reply #9 on: September 19, 2021, 11:08:36 pm »
Replaced it by ColorToHLS which has been there all the time (had not used it because I never know whether the H,L,S output covers the full byte range).

Put the component on my github now: https://github.com/wp-xyz/captcha_component. Maybe I ask for OPM integration later.

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1153
  • Professional amateur ;-P
Re: Lazarus implementation of a CAPTCHA
« Reply #10 on: September 19, 2021, 11:20:13 pm »
Hey WP,

Replaced it by ColorToHLS which has been there all the time (had not used it because I never know whether the H,L,S output covers the full byte range).

Awesome sauce!!! I'll switch to the cloned version of your repo instead of the zip file you provided erlyer, THANKS!!

Put the component on my github now: https://github.com/wp-xyz/captcha_component. Maybe I ask for OPM integration later.

Please do include it on OPM !!

And would it be too much to ask to create a thread on the Third Party forum to announce it? A bit of publicity wouldn't harm ;)

Can't say this enough: Many thanks for taking the challenge and making this awesome version!!

Cheers,
Gus
Lazarus 3.99(main) FPC 3.3.1(main) Ubuntu 23.10 64b Dark Theme
Lazarus 3.0.0(stable) FPC 3.2.2(stable) Ubuntu 23.10 64b Dark Theme
http://github.com/gcarreno

CM630

  • Hero Member
  • *****
  • Posts: 1199
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Lazarus implementation of a CAPTCHA
« Reply #11 on: September 20, 2021, 12:34:51 pm »
I have modified the source code, but now it shows empty spaces instead of letters:


Code: Pascal  [Select][+][-]
  1.  
  2. function TCAPTCHA.GenerateCAPTCHAString: string;
  3. const
  4.   NoOfChars = 10;
  5. var
  6.   validChar: String;
  7.   i: Integer;
  8. begin
  9.   Result:= EmptyStr;
  10.   validChar:= EmptyStr;
  11.   if TCharCase.Number in FCharCase then
  12.     validChar:= validChar + '123456789';
  13.  
  14.  
  15.   if TCharCase.Lower in FCharCase then
  16.     validChar:= validChar + 'абвгдежзийклмнопрстуфхцчшщъьюя';
  17.     //validChar:= validChar + 'abcdefghijklmnopqrstuvwxyz';
  18.  
  19.  
  20.   if TCharCase.Upper in FCharCase then
  21.     validChar:= validChar + 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЬЮЯ';
  22.     //validChar:= validChar + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  23.  
  24.  
  25.   SetLength(Result, NoOfChars);
  26.  
  27.  
  28.   for i:= 1 to NoOfChars do
  29.     Result[i]:= validChar[Random(Length(validChar)) + 1];
  30. end;      
Лазар 4,0RC1 32 bit (sometimes 64 bit); FPC3,2,2

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1153
  • Professional amateur ;-P
Re: Lazarus implementation of a CAPTCHA
« Reply #12 on: September 20, 2021, 02:38:05 pm »
Hey CM630,

I have modified the source code, but now it shows empty spaces instead of letters:

AAHHHH, Crap, the UTF8 ugly monster rears it's head!!

Looks like using TLogFont instead of TFont is more hassle than it should :(

Could I advise you that you use WP's implementation instead?: captcha_component and let us know if you can use Cyrillic with it?

I really need to pester WP into announcing his implementation on Third Part cuz mine is now proving itself to be more of a crappy solution than previously anticipated!!

Sorry for the inconvenience!!

Cheers,
Gus
Lazarus 3.99(main) FPC 3.3.1(main) Ubuntu 23.10 64b Dark Theme
Lazarus 3.0.0(stable) FPC 3.2.2(stable) Ubuntu 23.10 64b Dark Theme
http://github.com/gcarreno

CM630

  • Hero Member
  • *****
  • Posts: 1199
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Lazarus implementation of a CAPTCHA
« Reply #13 on: September 20, 2021, 03:57:59 pm »

Could I advise you that you use WP's implementation instead?: captcha_component and let us know if you can use Cyrillic with it?
I tried to try it. I think that it will need some more significant modifications to provide multilanguage support.
I got to the last line in the code below.


Code: Pascal  [Select][+][-]
  1. procedure TCaptcha.InitText(ACount: Integer; KeepExisting: Boolean);
  2. var
  3.   i, j, n: Integer;
  4.   ok: Boolean;
  5.   AllChars: string = 'abcdefghijklmnopqrstuvw';
  6. begin
  7.   if (FOptions * [coUppercase, coLowerCase, coNumbers] <> []) and
  8.      (FOptions * [coFont1, coFont2] <> []) then
  9.   begin
  10.     if KeepExisting then
  11.       n := Length(FCaptchaChars)
  12.     else
  13.       n := 0;
  14.     // Get random captcha characters, but keep previously assigned chars.
  15.     SetLength(FCaptchaChars, ACount);
  16.     for i := n to High(FCaptchaChars) do
  17.     begin
  18.       // Pick random character
  19.       repeat
  20.         j := Random(3);
  21.         ok := true;
  22.         if (j = 0) and (coUppercase in FOptions) then
  23.         begin
  24.           //FCaptchaChars[i].Character := char(ord('A') + Random(26));
  25.           FCaptchaChars[i].Character := char(UTF8Copy(AllChars,random(UTF8Length(AllChars)),1));  
  26. ...
  27.  
                                                           

The problem seems to be here:

Quote
TCaptchaChar = record
    Character: Char;      // Character
    Angle: Integer;       // Rotation angle of character, in degrees
    Position: TPoint;     // Position of character within buffer bitmap (for TextOut)
    FontIndex: Integer;   // Index of font to be used
    Color: TColor;        // Random color of the character
  end; 

Or precisely in Character: Char;

I think that Char is not going well with UTF8, and it is widely used in WPs code.
Лазар 4,0RC1 32 bit (sometimes 64 bit); FPC3,2,2

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1153
  • Professional amateur ;-P
Re: Lazarus implementation of a CAPTCHA
« Reply #14 on: September 20, 2021, 04:13:08 pm »
Hey CM630,

Or precisely in Character: Char;
I think that Char is not going well with UTF8, and it is widely used in WPs code.

I think you're right, having a one byte for the characters will not work in a UTF8 solution!!

Well, I've asked WP on this issue if he was willing to:
a) Add UTF8 support
b) Allow the user to set the valid characters

So let's wait for what he decides on the matter.

In the meantime, I'm sorry for the inconvenience. UTF8 is always hard and we Latin alphabet users often forget our non Latin alphabet co-programmers, which is a shame and I've been guilty of doing it myself :(
My deepest apologies for that!!

Cheers,
Gus
Lazarus 3.99(main) FPC 3.3.1(main) Ubuntu 23.10 64b Dark Theme
Lazarus 3.0.0(stable) FPC 3.2.2(stable) Ubuntu 23.10 64b Dark Theme
http://github.com/gcarreno

 

TinyPortal © 2005-2018