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)
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

TheRealLokiSenior DeveloperCommented:
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
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.
Wim ten BrinkSelf-employed developerCommented:
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? ;-)
Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

lopemAuthor Commented:
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 ( 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.
  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;


Wim ten BrinkSelf-employed developerCommented:
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.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
lopemAuthor Commented:
best regards
Manuel Lopez (lopem)
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.