Skip to content

Commit 1c74cca

Browse files
committed
typingdna.js v2.0
1 parent ecb57b4 commit 1c74cca

1 file changed

Lines changed: 67 additions & 49 deletions

File tree

typingdna.js

Lines changed: 67 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/**
2-
* TypingDNA - Typing Biometrics JavaScript API v1.2
3-
* http://typingdna.com/scripts/typingdna.js
4-
* Use your own copy. (hotlinks not recommended)
2+
* TypingDNA - Typing Biometrics JavaScript API v2.0
3+
* http://api.typingdna.com/scripts/typingdna.js
4+
* http://typingdna.com/scripts/typingdna.js (alternative)
55
*
6-
* @version 1.2
6+
* @version 2.0
77
* @author Raul Popa
8-
* @copyright Typingdna.com
8+
* @copyright SC TypingDNA SRL, http://typingdna.com
99
* @license http://www.apache.org/licenses/LICENSE-2.0
1010
* Licensed under the Apache License, Version 2.0 (the "License");
1111
* you may not use this file except in compliance with the License.
@@ -58,6 +58,9 @@ function TypingDNA(maxHistoryLength) {
5858
TypingDNA.prototype.getQuality = function(args) {
5959
return TypingDNA.getQuality.apply(this, arguments);
6060
}
61+
TypingDNA.prototype.getLength = function(args) {
62+
return TypingDNA.getLength.apply(this, arguments);
63+
}
6164
TypingDNA.prototype.maxHistoryLength = TypingDNA.maxHistoryLength;
6265
TypingDNA.prototype.defaultHistoryLength = TypingDNA.defaultHistoryLength;
6366
TypingDNA.prototype.maxSeekTime = TypingDNA.maxSeekTime;
@@ -68,46 +71,43 @@ function TypingDNA(maxHistoryLength) {
6871
TypingDNA.maxSeekTime = 1500;
6972
TypingDNA.maxPressTime = 300;
7073
TypingDNA.defaultHistoryLength = 500;
71-
// 44 chars
72-
TypingDNA.chars = [97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 32, 39, 44, 46, 59, 63, 45, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57];
74+
TypingDNA.keyCodes = [65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,32,222,188,190,186,187,189,191,48,49,50,51,52,53,54,55,56,57];
7375
TypingDNA.pt1 = TypingDNA.ut1 = (new Date).getTime();
7476
TypingDNA.wfk = [];
7577
TypingDNA.sti = [];
7678
TypingDNA.skt = [];
7779
TypingDNA.rkc = [];
7880
TypingDNA.lastDownKey;
7981
TypingDNA.prevKeyCode = 0;
80-
TypingDNA.zl = 0.000000000001;
82+
TypingDNA.zl = 0.0000001;
83+
8184
TypingDNA.keydown = function(e) {
82-
TypingDNA.lastDownKey = e.which;
83-
}
84-
TypingDNA.keypress = function(e) {
8585
var t0 = TypingDNA.pt1;
86-
TypingDNA.pt1 = (new Date).getTime();
87-
var rkco = e.which;
88-
var seekTotal = TypingDNA.pt1 - t0;
89-
var startTime = TypingDNA.pt1;
90-
var downKey = TypingDNA.lastDownKey;
91-
TypingDNA.wfk[downKey] = 1;
92-
TypingDNA.skt[downKey] = seekTotal;
93-
TypingDNA.sti[downKey] = startTime;
94-
TypingDNA.rkc[downKey] = rkco;
86+
if (!e.shiftKey || TypingDNA.isMobile()) {
87+
TypingDNA.pt1 = (new Date).getTime();
88+
var keyCode = e.keyCode;
89+
var seekTotal = TypingDNA.pt1 - t0;
90+
var startTime = TypingDNA.pt1;
91+
TypingDNA.wfk[keyCode] = 1;
92+
TypingDNA.skt[keyCode] = seekTotal;
93+
TypingDNA.sti[keyCode] = startTime;
94+
}
9595
}
9696
TypingDNA.keyup = function(e) {
9797
var ut = (new Date).getTime();
98-
var upKey = e.which;
99-
if (TypingDNA.wfk[upKey] == 1) {
100-
var keyCode = TypingDNA.rkc[upKey];
101-
var pressTime = ut - TypingDNA.sti[upKey];
102-
var seekTime = TypingDNA.skt[upKey];
103-
var arr = [keyCode, seekTime, pressTime, TypingDNA.prevKeyCode, ut];
104-
TypingDNA.history.add(arr);
105-
TypingDNA.prevKeyCode = keyCode;
106-
TypingDNA.wfk[upKey] = 0;
98+
if (!e.shiftKey || TypingDNA.isMobile()) {
99+
var keyCode = e.keyCode;
100+
if (TypingDNA.wfk[keyCode] == 1) {
101+
var pressTime = ut - TypingDNA.sti[keyCode];
102+
var seekTime = TypingDNA.skt[keyCode];
103+
var arr = [keyCode, seekTime, pressTime, TypingDNA.prevKeyCode, ut];
104+
TypingDNA.history.add(arr);
105+
TypingDNA.prevKeyCode = keyCode;
106+
}
107107
}
108+
TypingDNA.wfk[keyCode] = 0;
108109
}
109110
TypingDNA.element.addEventListener("keydown", TypingDNA.keydown);
110-
TypingDNA.element.addEventListener("keypress", TypingDNA.keypress);
111111
TypingDNA.element.addEventListener("keyup", TypingDNA.keyup);
112112

113113
/**
@@ -170,10 +170,10 @@ function TypingDNA(maxHistoryLength) {
170170
var pressHistSD = Math.round(TypingDNA.math.sd(histPrtF));
171171
var seekHistSD = Math.round(TypingDNA.math.sd(histSktF));
172172
var charMeanTime = seekHistMean + pressHistMean;
173-
var pressRatio = TypingDNA.math.rd((pressHistMean + zl) / (charMeanTime + zl), 3);
174-
var seekToPressRatio = TypingDNA.math.rd((1 - pressRatio)/pressRatio, 3);
175-
var pressSDToPressRatio = TypingDNA.math.rd((pressHistSD + zl) / (pressHistMean + zl), 3);
176-
var seekSDToPressRatio = TypingDNA.math.rd((seekHistSD + zl) / (pressHistMean + zl), 3);
173+
var pressRatio = TypingDNA.math.rd((pressHistMean + zl) / (charMeanTime + zl), 4);
174+
var seekToPressRatio = TypingDNA.math.rd((1 - pressRatio)/pressRatio, 4);
175+
var pressSDToPressRatio = TypingDNA.math.rd((pressHistSD + zl) / (pressHistMean + zl), 4);
176+
var seekSDToPressRatio = TypingDNA.math.rd((seekHistSD + zl) / (pressHistMean + zl), 4);
177177
var cpm = Math.round(6E4 / (charMeanTime + zl));
178178
for (var i in obj.arr) {
179179
var rev = obj.arr[i][1].length;
@@ -187,34 +187,34 @@ function TypingDNA(maxHistoryLength) {
187187
case 0:
188188
break;
189189
case 1:
190-
var seekMean = TypingDNA.math.rd((obj.arr[i][0][0] + zl) / (seekHistMean + zl), 3);
190+
var seekMean = TypingDNA.math.rd((obj.arr[i][0][0] + zl) / (seekHistMean + zl), 4);
191191
break;
192192
default:
193193
var arr = TypingDNA.math.fo(obj.arr[i][0]);
194-
seekMean = TypingDNA.math.rd((TypingDNA.math.avg(arr) + zl) / (seekHistMean + zl), 3);
195-
seekSD = TypingDNA.math.rd((TypingDNA.math.sd(arr) + zl) / (seekHistSD + zl), 3);
194+
seekMean = TypingDNA.math.rd((TypingDNA.math.avg(arr) + zl) / (seekHistMean + zl), 4);
195+
seekSD = TypingDNA.math.rd((TypingDNA.math.sd(arr) + zl) / (seekHistSD + zl), 4);
196196
}
197197
switch (obj.arr[i][1].length) {
198198
case 0:
199199
break;
200200
case 1:
201-
var pressMean = TypingDNA.math.rd((obj.arr[i][1][0] + zl) / (pressHistMean + zl), 3);
201+
var pressMean = TypingDNA.math.rd((obj.arr[i][1][0] + zl) / (pressHistMean + zl), 4);
202202
break;
203203
default:
204204
var arr = TypingDNA.math.fo(obj.arr[i][1]);
205-
pressMean = TypingDNA.math.rd((TypingDNA.math.avg(arr) + zl) / (pressHistMean + zl), 3);
206-
pressSD = TypingDNA.math.rd((TypingDNA.math.sd(arr) + zl) / (pressHistSD + zl), 3);
205+
pressMean = TypingDNA.math.rd((TypingDNA.math.avg(arr) + zl) / (pressHistMean + zl), 4);
206+
pressSD = TypingDNA.math.rd((TypingDNA.math.sd(arr) + zl) / (pressHistSD + zl), 4);
207207
}
208208
switch (obj.arr[i][2].length) {
209209
case 0:
210210
break;
211211
case 1:
212-
var postMean = TypingDNA.math.rd((obj.arr[i][2][0] + zl) / (seekHistMean + zl), 3);
212+
var postMean = TypingDNA.math.rd((obj.arr[i][2][0] + zl) / (seekHistMean + zl), 4);
213213
break;
214214
default:
215215
var arr = TypingDNA.math.fo(obj.arr[i][2]);
216-
postMean = TypingDNA.math.rd((TypingDNA.math.avg(arr) + zl) / (seekHistMean + zl), 3);
217-
postSD = TypingDNA.math.rd((TypingDNA.math.sd(arr) + zl) / (seekHistSD + zl), 3);
216+
postMean = TypingDNA.math.rd((TypingDNA.math.avg(arr) + zl) / (seekHistMean + zl), 4);
217+
postSD = TypingDNA.math.rd((TypingDNA.math.sd(arr) + zl) / (seekHistSD + zl), 4);
218218
}
219219
delete obj.arr[i][2];
220220
delete obj.arr[i][1];
@@ -241,14 +241,15 @@ function TypingDNA(maxHistoryLength) {
241241
TypingDNA.apu(arr, seekHistSD);
242242
for (var c = 0; c <= 6; c++) {
243243
for (var i = 0; i < 44; i++) {
244-
var keyCode = TypingDNA.chars[i];
244+
var keyCode = TypingDNA.keyCodes[i];
245245
var val = obj.arr[keyCode][c];
246246
if (val == 0 && c > 0) {
247247
val = 1;
248248
}
249249
TypingDNA.apu(arr, val);
250250
}
251251
}
252+
TypingDNA.apu(arr, TypingDNA.isMobile());
252253
return arr.join(",");
253254
}
254255
TypingDNA.apu = function(arr, val) {
@@ -265,7 +266,7 @@ function TypingDNA(maxHistoryLength) {
265266
for (var i = 0; i < len; i++) {
266267
sum += arr[i];
267268
}
268-
return this.rd(sum / len, 3);
269+
return this.rd(sum / len, 4);
269270
}
270271
TypingDNA.math.sd = function(arr) {
271272
var len = arr.length;
@@ -338,8 +339,8 @@ function TypingDNA(maxHistoryLength) {
338339
break;
339340
default:
340341
var historyStackObj = {};
341-
for (var i in TypingDNA.chars) {
342-
historyStackObj[TypingDNA.chars[i]] = [
342+
for (var i in TypingDNA.keyCodes) {
343+
historyStackObj[TypingDNA.keyCodes[i]] = [
343344
[],
344345
[],
345346
[]
@@ -351,10 +352,10 @@ function TypingDNA(maxHistoryLength) {
351352
var seekTime = arr[1];
352353
var pressTime = arr[2];
353354
var prevKeyCode = arr[3];
354-
if (TypingDNA.chars.indexOf(keyCode) != -1) {
355+
if (TypingDNA.keyCodes.indexOf(keyCode) != -1) {
355356
if (seekTime <= TypingDNA.maxSeekTime) {
356357
historyStackObj[keyCode][0].push(seekTime);
357-
if (prevKeyCode != 0 && TypingDNA.chars.indexOf(prevKeyCode) != -1) {
358+
if (prevKeyCode != 0 && TypingDNA.keyCodes.indexOf(prevKeyCode) != -1) {
358359
historyStackObj[prevKeyCode][2].push(seekTime);
359360
}
360361
}
@@ -391,4 +392,21 @@ function TypingDNA(maxHistoryLength) {
391392
return tReturn > 1 ? 1 : tReturn;
392393
}
393394

395+
TypingDNA.getLength = function(typingPattern) {
396+
return Number(typingPattern.split(",")[1]);
397+
}
398+
399+
TypingDNA.isMobile = function() {
400+
var check = 0;
401+
(function(a) {
402+
if (
403+
/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i
404+
.test(a) ||
405+
/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i
406+
.test(a.substr(0, 4))) {
407+
check = 1
408+
}
409+
})(navigator.userAgent || navigator.vendor || window.opera);
410+
return check;
411+
}
394412
}

0 commit comments

Comments
 (0)