[Last Call] Learn how to a build a cloud-first strategyRegister Now


measure keystrokes

Posted on 2004-11-22
Medium Priority
Last Modified: 2013-11-15
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)
Question by:lopem
LVL 17

Expert Comment

ID: 12650940
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

Expert Comment

ID: 12653204
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.
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12654688
function RDTSC: Int64;
  dw $310F  {BASM doesn't support RDTSC}

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? ;-)
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.


Author Comment

ID: 12656442
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.
        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

                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

                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.

                  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;


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

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

procedure Register;


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

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

destructor THPCounter.Destroy;
  inherited Destroy;

function THPCounter.Read: string;
  Result:=IntToStr(Round(1000000 * (lpPerformanceCount2 -
                       lpPerformanceCount1) / Frequency));

function THPCounter.ReadInt: TLargeInteger;
  Result:=Round(1000000 * (lpPerformanceCount2 -
                       lpPerformanceCount1) / Frequency);

procedure THPCounter.SetCop(Value: string);

procedure THPCounter.Start;


LVL 17

Accepted Solution

Wim ten Brink earned 375 total points
ID: 12656611
Determining the user by the way he enters his password? Interesting. You could indeed check the typing speed of the current user and see if it matches his profile. It's not easy to fool such a system but some users have a very variable typing speed. (Especially people with risks of RSI.) My own speed even differs at times since sometimes I type with my left hand, other times with my right. And in a few situations where I have to type a lot, I use both hands. (Like now.)

Handling multiple keypresses aren't too difficult to handle but you have to build a list of keys that are pressed at that moment. Every key generates a message, which provides information about the key that is pressed. What you would have to do is maintain a list where you can store the time when a key was last pressed and find that key again once it is released.
Basically, this

User presses key:
* Get timestamp
* Add a keyrecord to list
* Set key value to keyrecord
* Set timestamp to key record

User releases key
* Get timestamp
* Find key value in list and retrieve keyrecord
* Exit if no keyrecord is found. (Can happen sometimes)
* Remove keyrecord from list
* calculate difference between keyrecord.timestamp and the other timestamp

Be aware that since these are timing issues, you need to get the timestamp as fast as possible, store it so whatever time the rest of the process takes, it won't add up to the timestamp.

Author Comment

ID: 12713239
best regards
Manuel Lopez (lopem)

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The core idea of this article is to make you acquainted with the best way in which you can export Exchange mailbox to PST format.
Today as you open your Outlook, you witness an error message: “Outlook is using an old copy of your Outlook Data File…”. Probably, Outlook is accessing an old OST file.
The viewer will learn how to successfully create a multiboot device using the SARDU utility on Windows 7. Start the SARDU utility: Change the image directory to wherever you store your ISOs, this will prevent you from having 2 copies of an ISO wit…
XMind Plus helps organize all details/aspects of any project from large to small in an orderly and concise manner. If you are working on a complex project, use this micro tutorial to show you how to make a basic flow chart. The software is free when…
Suggested Courses

834 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question