A open source key stroke counter for windows

EDIT: An upgrade.
The name for the program is currently, Keycounter. Hosted in my repository. Written in C++. I use g++ to compile it. Here is the compiled binaries. Keycumcounter only count the total keystroke+mouse clicks, but save log in a human readable way.

The program count every keystroke, mouse clicks and how far the mouse have moved(in pixels, rounded). Save the data each hour as a human-not-readable text file.
Why would it be useful if it's not human-readable(unless you have a hash table of Virtual-Key Codes and read HEX like decimals)? Because the data are suppose to be analyzed by some other program. I might write one, or not. For example, write a script with php that analyze the data and store it in a mysql database. Then someone can use Google Chart API to plot the data in some way.

The file structure is so easy, anyone can make use of it.
Example structure:

2009,2,28,14,1|3A,DE|16,FF|334,

Structure of the file:
Each line is a entry. Values separated by a comma.
Year, Month, Date, Hour, Rest of the data
The time is UTC time.

The rest of the data are keystroke counts, stored as a string represent a hex value.
1|3A means the 0x01 key(which is a mouse click) was stroked 58 times. Everything according to the Virtual-Key Codes.
There is a special one don't have anything to do Virtual-Key Code. That's FF. FF|334 means the mouse have moved a total distance of 820 pixels(a very rough estimate).

Note, sum of every keystroke count doesn't mean the total keystroke you have done. For example. The left ctrl count as 2 separate keystrokes. A left keyboard stroke and a left ctrl stroke.

Features:

  • Low CPU usage. 0% on my EEEPC 1000H.
  • Theoretically, the key capture rate is 100%. In practice, might be 99.9999999%
  • Low memory usage. Well it's not that low, over 1MB.
  • Portable log file

Credits:

Alternatives:
Whatpulse, Keystroke Counter Tool by Tim Koschützki, KeyCounter by skwire and KeyCounter.

Source. If you can't be bothered to check the repository.

#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <windows.h>
 
typedef short (*KeyState)(int);
unsigned int a[256];
int z[4];
//This is from http://bbs.emath.ac.cn/viewthread.php?tid=1207&page=6&fromuid=310#pid16108
//by  gxqcn, http://emath.ac.cn
unsigned long isqrt( unsigned long n ){
    unsigned long t;
    unsigned long ret = 0;
 
    #define SQRT_CORE(x)        \
        t = ret + (1UL<<(x));   \
        ret >>= 1;              \
        if ( n >= t )           \
        {                       \
            n -= t;             \
            ret += (1UL<<(x));  \
        }
 
    SQRT_CORE(30);
    SQRT_CORE(28);
    SQRT_CORE(26);
    SQRT_CORE(24);
    SQRT_CORE(22);
    SQRT_CORE(20);
    SQRT_CORE(18);
    SQRT_CORE(16);
    SQRT_CORE(14);
    SQRT_CORE(12);
    SQRT_CORE(10);
    SQRT_CORE(8);
    SQRT_CORE(6);
    SQRT_CORE(4);
    SQRT_CORE(2);
    SQRT_CORE(0);
 
    #undef SQRT_CORE
 
    return ret;
}
inline int press(int i){
	return (GetAsyncKeyState(i) & 0x8000);
}
void savetmp(void){
	int i=0;
	if(a[0]!=0){
		FILE * pFile;
		pFile = fopen ("tmp.txt","w");
		if(pFile!=NULL){
			fprintf(pFile,"%d %d %d %d ",z[3],z[2],z[1],z[0]);
			for(i=1;i<256;i++){
				if(a[i]!=0){
					fprintf(pFile,"%d %d ",i,a[i]);
				}
			}
			fclose (pFile);
	  }
	}
}
inline void savelog(void){
	if(a[0]!=0 || a[255]>0){
		FILE * pFile;
		pFile = fopen ("log.txt","a");
		if(pFile!=NULL){
			fprintf(pFile,"%d,%d,%d,%d,",z[3]+1900,z[2]+1,z[1],z[0]);
			for(int i=1;i<256;i++){
				if(a[i]!=0){
					fprintf(pFile,"%X|%X,",i,a[i]);
				}
			}
			fprintf(pFile,"\n");
			fclose (pFile);
	  }
	}
 
};
inline void readtmp(void){
	FILE * pFile;
	pFile = fopen ("tmp.txt","r");
	time_t rawtime;
	tm* ptm;
	time(&rawtime);
	ptm = gmtime(&rawtime);
	int i=0;
	if (pFile!=NULL){
		fscanf (pFile, "%d %d %d %d", &z[3],&z[2],&z[1],&z[0]);
		while (!feof(pFile)) {
			  fscanf(pFile, "%d", &i);
			  fscanf(pFile, "%d", &a[i]);
		}
		a[0] = 1;
		fclose (pFile);
		if(z[0] != ptm->tm_hour || z[1] != ptm->tm_mday
		|| z[2] != ptm->tm_mon || z[3] != ptm->tm_year){
			savelog();
			z[0] = ptm->tm_hour;
			z[1] = ptm->tm_mday;
			z[2] = ptm->tm_mon;
			z[3] = ptm->tm_year;
			for(int i=0;i<256;++i) a[i]=0;
		}
	}else{
		z[0] = ptm->tm_hour;
		z[1] = ptm->tm_mday;
		z[2] = ptm->tm_mon;
		z[3] = ptm->tm_year;
	}
};
 
int main(int argc, char * argv[]){
	POINT pt;
	GetCursorPos(&pt);
	const int stime =40; 
	int i=0,o,clx=pt.x,cly=pt.y;
	//initialize variables
	bool b[256];
	for(i=0;i<256;++i){a[i]=0;b[i]=false;}
	//Read tmp file
	readtmp();
	//ini time
	time_t rawtime;
	tm * ptm;
 
	atexit(savetmp);
	while(1){
		//Save log if hour is different
		time(&rawtime);
		ptm = gmtime(&rawtime);
		if(z[0] != ptm->tm_hour){
			savelog();
			z[0] = ptm->tm_hour;
			z[1] = ptm->tm_mday;
			z[2] = ptm->tm_mon;
			z[3] = ptm->tm_year;
			for(i=0;i<256;++i) a[i]=0;
		}
 
		//keystorke counter
		for(i=1;i<255;++i){
			o = press(i);
			if(!b[i] && o){
				b[i]=true;
			}else if(b[i] && o==0){
				b[i]=false;
				++a[i];
				++a[0];
				//std::cout<<i<<"-";
			}
		}
		//mouse distant tracker
		GetCursorPos(&pt);
		clx -= pt.x;
		cly -= pt.y;
		a[255]+=isqrt((unsigned int)(clx*clx+cly*cly));
		clx=pt.x;
		cly=pt.y;
		Sleep(stime);
	}
   return 0;
}
AttachmentSize
keycounter.zip3.08 KB
keycumcounter.zip2.65 KB

Comments

Anonymous's picture

Very practical post for key

Very practical post for key counter in windows. I appreciate your idea and works on code. But it’s troublesome to read the writings as the fonts are too small. So it’s difficult to understand.

Puppies for sale

Post new comment

  • Allowed HTML tags: <img> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <span> <fn>
  • Lines and paragraphs break automatically.
  • Use [fn]...[/fn] (or <fn>...</fn>) to insert automatically numbered footnotes.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>. The supported tag styles are: <foo>, [foo].
  • Mathematical equations and graphs can be added between [tex] and [/tex], [graph] and [/graph] tags.
  • Textual smileys will be replaced with graphical ones.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
              ____    _      __  __                
_ __ ___ | _ \ | |__ \ \/ / _ _ __ __
| '_ ` _ \ | |_) | | '_ \ \ / | | | | \ \ / /
| | | | | | | __/ | |_) | / \ | |_| | \ V /
|_| |_| |_| |_| |_.__/ /_/\_\ \__,_| \_/
Enter the code depicted in ASCII art style.
Honey Pot that kill bots