measure keystrokes

Posted on 2004-11-22
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

    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
    LVL 4

    Expert Comment

    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
    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? ;-)
    LVL 3

    Author Comment

    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;


    LVL 17

    Accepted Solution

    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.
    LVL 3

    Author Comment

    best regards
    Manuel Lopez (lopem)

    Featured Post

    Looking for New Ways to Advertise?

    Engage with tech pros in our community with native advertising, as a Vendor Expert, and more.

    Join & Write a Comment

    Suggested Solutions

    Article by: Rob
    Notes 8.5 Archiving Steps and Tips This article covers setting up a Notes archive, and helps understand some of the menu choices making setting up and maintaining a Notes archive file easier.
    Storage devices are generally used to save the data or sometime transfer the data from one computer system to another system. However, sometimes user accidentally erased their important data from the Storage devices. Users have to know how data reco…
    This video demonstrates basic masking and how to edit the mask to reveal the desired image.
    An overview on how to enroll an hourly employee into the employee database and how to give them access into the clock in terminal.

    729 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

    Need Help in Real-Time?

    Connect with top rated Experts

    20 Experts available now in Live!

    Get 1:1 Help Now