Link to home
Start Free TrialLog in
Avatar of Manuel Lopez-Michelone
Manuel Lopez-MicheloneFlag for Mexico

asked on

measure keystrokes

Hi experts,

I want to know if there is a way to measure the time used by someone who strokes any key of the keyboard. I want to measure the time between keystrokes. Any code or ideas available?

best regards
Manuel Lopez (lopem)
Avatar of TheRealLoki
TheRealLoki
Flag of New Zealand image

if it is in your application, you can use the "onkeypress" event on the control
and get the current time. (or gettickcount for more precision)
between this time, and the previous time.
also keeping track of the number of keypresses
Avatar of Colin_Dawson
Colin_Dawson

If you're talking about when using any program in windows, you'll need to install a keyboard hook.  Take a look at SetWindowHook and the WH_KEYBOARD property. You can also install the hook at application level, if you're looking to time in your application only.

As for getting the time between keystrokes there's two posibilites that you can use.  Depending on the accuracy that you require.

The GetTickCount function is easy to use, but not very accurate. It measures times in milliseconds, but the smallest time that it can measure is 100ms, not really that useful for a fast user who can type more than ten characters per second.

A better timer is the QueryPerformanceCounter function that can measure times in the nanosecond, this is dependent on the processor, but it's the most accurate that you can get.
function RDTSC: Int64;
asm
  dw $310F  {BASM doesn't support RDTSC}
end;

Above function will not measure time, but processor ticks. It's the most accurate information that you can get since it's based on a counter within every Pentium processor. However, it does depend on the processsor speed. Faster computers will have more ticks per second than slow computers.

As Colin suggested, a keyhook would be the most precise option, but be aware that users can press multiple keys at the same time. How do you think to handle those situations? ;-)
Avatar of Manuel Lopez-Michelone

ASKER

Hi again experts,

Let me explain a little bit more: The main idea is to try to identify an user on a computer,  considering the way he/she types his/her password. For some natural reasons, people writes the same things on a keyboard with the same rythm (average speaking). I am working on some statistical tests to try to build a "keystroke profile".

Most systems use passwords to validate users. What about validate a user using a password and the keystroke profile. In some sense I am looking for some digital signature difficult to recreate by an impostor even he/she knows a user password. It seems  to me a very interesting idea.

Around workshop_Alex's function, I will try it, thanks! (and I don't have any idea how to cope with users pressing more than one key at a time). Also, I found this little component (see below) of a High Resolution Counter (www.torry.ru page). There are few time counters and I am trying all of them looking for the best.

In fact, I am not very sure if a keystroke profile can be build, but I think is worth to try. In the middle I am learning a lot of new things ;-)

best regards
Manuel Lopez (lopem)

{
----------------------------------------------------------
MAS-CompMaker was used to generate this code
MAS-CompMaker, copyright(c) 2000, Mats Asplund / MAs Prod.
----------------------------------------------------------

Component Name: THPCounter
        Author: Mats Asplund
      Creation: 2000-09-17
       Version: 1.1
   Description: A high-precision counter/timer. Retrieves time differences
                downto microsec.
        Credit:
        E-mail: mats.asplund@telia.com
          Site: http://go.to/masdp
  Legal issues: Copyright (C) 2000 by Mats Asplund


         Usage: This software is provided 'as-is', without any express or
                implied warranty.  In no event will the author be held liable
                for any  damages arising from the use of this software.

                Permission is granted to anyone to use this software for any
                purpose, including commercial applications, and to alter it
                and redistribute it freely, subject to the following
                restrictions:

                1. The origin of this software must not be misrepresented,
                   you must not claim that you wrote the original software.
                   If you use this software in a product, an acknowledgment
                   in the product documentation would be appreciated but is
                   not required.

                2. Altered source versions must be plainly marked as such, and
                   must not be misrepresented as being the original software.

                3. This notice may not be removed or altered from any source
                   distribution.

                4. If you decide to use this software in any of your applications.
                   Send me an EMail address and tell me about it.

Quick Reference:
                THPCounter inherits from TComponent.

                Key-Methods:
                  Start:    Starts the counter. Place this call just before the
                            code you want to measure.

                  Read:     Reads the counter as a string. Place this call just
                            after the code you want to measure.

                  ReadInt:  Reads the counter as an Int64. Place this call just
                            after the code you want to measure.
--------------------------------------------------------------------------------
}
unit HPCounter;

interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls, ExtCtrls;

type
  TInt64 = TLargeInteger;
  THPCounter = class(TComponent)
private
  Frequency: TLargeInteger;
  lpPerformanceCount1: TLargeInteger;
  lpPerformanceCount2: TLargeInteger;
  FCopyright: string;
  procedure SetCop(Value: string);
  { Private declarations }
public
  constructor Create(AOwner: TComponent); override;
  destructor Destroy; override;
  procedure Start;
  function Read: string;
  function ReadInt: TLargeInteger;
  { Private declarations }
published
  property Copyright: string read FCopyright write SetCop;
  { Published declarations }
end;


procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('MAs Prod.', [THPCounter]);
end;

constructor THPCounter.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FCopyright:='Copyright (c) 2000, MAs Prod. / Mats Asplund';
end;

destructor THPCounter.Destroy;
begin
  inherited Destroy;
end;

function THPCounter.Read: string;
begin
  QueryPerformanceCounter(TInt64((@lpPerformanceCount2)^));
  QueryPerformanceFrequency(TInt64((@Frequency)^));
  Result:=IntToStr(Round(1000000 * (lpPerformanceCount2 -
                       lpPerformanceCount1) / Frequency));
end;

function THPCounter.ReadInt: TLargeInteger;
begin
  QueryPerformanceCounter(TInt64((@lpPerformanceCount2)^));
  QueryPerformanceFrequency(TInt64((@Frequency)^));
  Result:=Round(1000000 * (lpPerformanceCount2 -
                       lpPerformanceCount1) / Frequency);
end;

procedure THPCounter.SetCop(Value: string);
begin
  Exit;
end;

procedure THPCounter.Start;
begin
  QueryPerformanceCounter(TInt64((@lpPerformanceCount1)^));
end;

end.

ASKER CERTIFIED SOLUTION
Avatar of Wim ten Brink
Wim ten Brink
Flag of Netherlands image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks!
best regards
Manuel Lopez (lopem)