I am working on a project in which I have to develop bio-passwords based on user's keystroke style. Suppose a user types a password for 20 times, his keystrokes are recorded, like
holdtime : time for which a particular key is pressed. digraph time : time it takes to press a different key.
suppose a user types a password " COMPUTER". I need to know the time for which every key is pressed. something like :
holdtime for the above password is
C-- 200ms O-- 130ms M-- 150ms P-- 175ms U-- 320ms T-- 230ms E-- 120ms R-- 300ms
The rational behind this is , every user will have a different holdtime. Say a old person is typing the password, he will take more time then a student. And it will be unique to a particular person. To do this project, I need to record the time for each key pressed. I would greatly appreciate if anyone can guide me in how to get these times.
Editing from here.. Language is not important, but I would prefer it in C. I am more interested in getting the dataset.
Record the KeyDown and KeyUp events, and do a diff on the timestamps of each.
http://code.activestate.com/recipes/203830/
Edit: You may want to check out wxPython, it should help you out:
http://www.wxpython.org/onlinedocs.php
in particular:
http://docs.wxwidgets.org/stable/wx_wxkeyevent.html#wxkeyevent
You mentioned you'd prefer it in C, but since you tagged it Python... :)
Also, since you say you're looking for building a dataset, I assume you'll have to invite users to type in arbitrary text, so you'll need some sort of interface (graphical or otherwise).
Here's a quick example using pygame. You can trivially modify it to ask users to type specific words, but, as it is, it'll just let the user type in arbitrary text, record pressing times for all keypresses, and print each hold and digraph times, in the order that the user typed it, when it exits (i.e., when the user presses Esc).
As Kibibu noticed, showing the user what he's typing in realtime introduces a delay which might mask real key-pressing times, so this code only displays what the user has typed when he types "Enter".
Update: it now calculates digraph as well as hold times (excluding Enter in both cases).
Update2: Per Adi's request, changed from displaying average to displaying each individual time, in order.
import sys
from collections import defaultdict
from time import time
import pygame
from pygame.key import name as keyname
from pygame.locals import *
# Mapping of a key to a list of holdtimes (from which you can average, etc)
holdtimes = defaultdict(list)
# Mapping of a key pair to a list of digraph times
digraphs = defaultdict(list)
# Keys which have been pressed down, but not up yet.
pending = {}
# Last key to be de-pressed, corresponding time).
last_key = None
# Text that the user has typed so far (one sublist for every Enter pressed)
typed_text = [[]]
def show_times():
all_text = [k for line in typed_text for k in line]
print "Holdtimes:"
for key in all_text:
print "%s: %.5f" % (key, holdtimes[key].pop(0))
print "Digraphs:"
for key1, key2 in zip(all_text, all_text[1:]):
print "(%s, %s): %.5f" % (key1, key2,
digraphs[(key1, key2)].pop(0))
def time_keypresses(events):
global last_key
for event in events:
if event.type == KEYDOWN:
# ESC exits the program
if event.key == K_ESCAPE:
show_times()
sys.exit(0)
t = pending[event.key] = time()
if last_key is not None:
if event.key != K_RETURN:
digraphs[(last_key[0], keyname(event.key))].append(t - last_key[1])
last_key = None
elif event.type == KEYUP:
if event.key == K_RETURN:
update_screen()
typed_text.append([])
pending.pop(event.key)
last_key = None
else:
t = time()
holdtimes[keyname(event.key)].append(t - pending.pop(event.key))
last_key = [keyname(event.key), t]
typed_text[-1].append(keyname(event.key))
# Any other event handling you might have would go here...
def update_screen():
global screen
screen.fill((255, 255, 255))
header_font = pygame.font.Font(None, 42)
header = header_font.render("Type away! Press 'Enter' to show.", True, (0, 0, 0))
header_rect = header.get_rect()
header_rect.centerx = screen.get_rect().centerx
header_rect.centery = screen.get_rect().centery - 100
text_font = pygame.font.Font(None, 32)
user_text = text_font.render("".join(typed_text[-1]) if typed_text[-1] else "...",
True, (0, 0, 255))
text_rect = user_text.get_rect()
text_rect.centerx = screen.get_rect().centerx
text_rect.centery = screen.get_rect().centery
screen.blit(header, header_rect)
screen.blit(user_text, text_rect)
pygame.display.update()
if __name__ == '__main__':
pygame.init()
window = pygame.display.set_mode((800, 600))
screen = pygame.display.get_surface()
update_screen()
while True:
time_keypresses(pygame.event.get())
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With