devicer.js 1.0.9 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devicer.js",
3
- "version": "1.0.9",
3
+ "version": "1.0.10",
4
4
  "description": "Open-Source Digital Fingerprinting Middleware",
5
5
  "main": "src/main.js",
6
6
  "scripts": {
@@ -1,46 +1,70 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.calculateConfidence = void 0;
3
+ exports.calculateConfidence = exports.compareDatasets = exports.compareArrays = void 0;
4
4
  const tlsh_1 = require("./tlsh");
5
- function compareArrays(arr1, arr2) {
5
+ function compareArrays(arr1, arr2, max_depth = 5) {
6
6
  let fields = 0;
7
7
  let matches = 0;
8
- const maxLength = Math.max(arr1.length, arr2.length);
8
+ // Ensure max_depth is not exceeded
9
+ if (max_depth <= 0) {
10
+ throw new Error("Max depth exceeded");
11
+ }
12
+ // Sort arrays to ensure consistent comparison
13
+ const sortedArr1 = arr1.map((item) => JSON.stringify(item)).sort().map((item) => {
14
+ try {
15
+ return JSON.parse(item);
16
+ }
17
+ catch (e) {
18
+ return undefined;
19
+ }
20
+ });
21
+ const sortedArr2 = arr2.map((item) => JSON.stringify(item)).sort().map((item) => {
22
+ try {
23
+ return JSON.parse(item);
24
+ }
25
+ catch (e) {
26
+ return undefined;
27
+ }
28
+ });
29
+ const maxLength = Math.min(arr1.length, arr2.length);
9
30
  for (let i = 0; i < maxLength; i++) {
10
- if (arr1[i] !== undefined && arr2[i] !== undefined) {
11
- fields++;
12
- if (Array.isArray(arr1[i]) && Array.isArray(arr2[i])) {
13
- const subData = compareArrays(arr1[i], arr2[i]);
14
- fields += subData[0] - 1; // Subtract 1 for the index itself
15
- matches += subData[1];
16
- }
17
- else if ((typeof arr1[i] == "object" && arr1[i]) &&
18
- (typeof arr2[i] == "object" && arr2[i])) {
19
- const subData = compareDatasets(arr1[i], arr2[i]);
20
- fields += subData[0] - 1; // Subtract 1 for the index itself
21
- matches += subData[1];
22
- }
23
- else if (arr1[i] === arr2[i]) {
24
- matches++;
25
- }
31
+ fields++;
32
+ if (Array.isArray(sortedArr1[i]) && Array.isArray(sortedArr2[i])) {
33
+ const subData = compareArrays(sortedArr1[i], sortedArr2[i], max_depth - 1);
34
+ fields += subData[0] - 1; // Subtract 1 for the index itself
35
+ matches += subData[1];
36
+ }
37
+ else if ((typeof sortedArr1[i] == "object" && sortedArr1[i]) &&
38
+ (typeof sortedArr2[i] == "object" && sortedArr2[i])) {
39
+ const subData = compareDatasets(sortedArr1[i], sortedArr2[i], max_depth - 1);
40
+ fields += subData[0] - 1; // Subtract 1 for the index itself
41
+ matches += subData[1];
42
+ }
43
+ if (arr1[i] === arr2[i]) {
44
+ matches++;
26
45
  }
27
46
  }
28
47
  return [fields, matches];
29
48
  }
30
- function compareDatasets(data1, data2) {
49
+ exports.compareArrays = compareArrays;
50
+ function compareDatasets(data1, data2, max_depth = 5) {
31
51
  let fields = 0;
32
52
  let matches = 0;
53
+ // Ensure max_depth is not exceeded
54
+ if (max_depth <= 0) {
55
+ throw new Error("Max depth exceeded");
56
+ }
33
57
  for (const key in data1) {
34
58
  if (data1[key] !== undefined && data2[key] !== undefined) {
35
59
  fields++;
36
60
  if ((typeof data1[key] == "object" && data1[key]) &&
37
61
  (typeof data2[key] == "object" && data2[key])) {
38
- const subData = compareDatasets(data1[key], data2[key]);
62
+ const subData = compareDatasets(data1[key], data2[key], max_depth - 1);
39
63
  fields += subData[0] - 1; // Subtract 1 for the key itself
40
64
  matches += subData[1];
41
65
  }
42
66
  else if (Array.isArray(data1[key]) && Array.isArray(data2[key])) {
43
- const subData = compareArrays(data1[key], data2[key]);
67
+ const subData = compareArrays(data1[key], data2[key], max_depth - 1);
44
68
  fields += subData[0] - 1; // Subtract 1 for the key itself
45
69
  matches += subData[1];
46
70
  }
@@ -51,23 +75,30 @@ function compareDatasets(data1, data2) {
51
75
  }
52
76
  return [fields, matches];
53
77
  }
78
+ exports.compareDatasets = compareDatasets;
54
79
  function calculateConfidence(data1, data2) {
55
- // Compare how many fields are the same in both datasets
56
- const [fields, matches] = compareDatasets(data1, data2);
57
- if (fields === 0 || matches === 0) {
58
- return 0;
80
+ try {
81
+ // Compare how many fields are the same in both datasets
82
+ const [fields, matches] = compareDatasets(data1, data2);
83
+ if (fields === 0 || matches === 0) {
84
+ return 0;
85
+ }
86
+ // Calculate the hash for each user data
87
+ const hash1 = (0, tlsh_1.getHash)(JSON.stringify(data1));
88
+ const hash2 = (0, tlsh_1.getHash)(JSON.stringify(data2));
89
+ // Compare the hashes to get their difference
90
+ const differenceScore = (0, tlsh_1.compareHashes)(hash1, hash2);
91
+ const inverseMatchScore = 1 - (matches / fields);
92
+ const x = 1.3 * differenceScore * inverseMatchScore;
93
+ if (inverseMatchScore === 0 || differenceScore === 0) {
94
+ return 100;
95
+ }
96
+ const confidenceScore = 100 / (1 + Math.E ** (-4.5 + (0.3 * x)));
97
+ return confidenceScore;
59
98
  }
60
- // Calculate the hash for each user data
61
- const hash1 = (0, tlsh_1.getHash)(JSON.stringify(data1));
62
- const hash2 = (0, tlsh_1.getHash)(JSON.stringify(data2));
63
- // Compare the hashes to get their difference
64
- const differenceScore = (0, tlsh_1.compareHashes)(hash1, hash2);
65
- const inverseMatchScore = 1 - (matches / fields);
66
- const x = 1.3 * differenceScore * inverseMatchScore;
67
- if (inverseMatchScore === 0 || differenceScore === 0) {
68
- return 100;
99
+ catch (error) {
100
+ console.error("Error calculating confidence:", error);
101
+ return 0; // Return 0 if an error occurs during comparison
69
102
  }
70
- const confidenceScore = 100 / (1 + Math.E ** (-4.5 + (0.3 * x)));
71
- return confidenceScore;
72
103
  }
73
104
  exports.calculateConfidence = calculateConfidence;
@@ -1,39 +1,83 @@
1
- import { getHash, compareHashes } from "./tlsh";
1
+ import { compareHashes, getHash } from "./tlsh";
2
2
  import { FPDataSet } from "../types/data";
3
3
 
4
- function compareArrays(arr1: any[], arr2: any[]): [number, number] {
4
+ export function compareArrays(
5
+ arr1: any[],
6
+ arr2: any[],
7
+ max_depth: number = 5,
8
+ ): [number, number] {
5
9
  let fields = 0;
6
10
  let matches = 0;
7
- const maxLength = Math.max(arr1.length, arr2.length);
8
- for (let i = 0; i < maxLength; i++) {
9
- if (arr1[i] !== undefined && arr2[i] !== undefined) {
10
- fields++;
11
- if (Array.isArray(arr1[i]) && Array.isArray(arr2[i])) {
12
- const subData = compareArrays(arr1[i], arr2[i]);
13
- fields += subData[0] - 1; // Subtract 1 for the index itself
14
- matches += subData[1];
15
- }
16
-
17
- else if (
18
- (typeof arr1[i] == "object" && arr1[i]) &&
19
- (typeof arr2[i] == "object" && arr2[i])
20
- ) {
21
- const subData = compareDatasets(arr1[i] as FPDataSet, arr2[i] as FPDataSet);
22
- fields += subData[0] - 1; // Subtract 1 for the index itself
23
- matches += subData[1];
11
+
12
+ // Ensure max_depth is not exceeded
13
+ if (max_depth <= 0) {
14
+ throw new Error("Max depth exceeded");
15
+ }
16
+
17
+ // Sort arrays to ensure consistent comparison
18
+ const sortedArr1 = arr1.map((item) => JSON.stringify(item)).sort().map(
19
+ (item) => {
20
+ try {
21
+ return JSON.parse(item);
22
+ } catch (e) {
23
+ return undefined;
24
24
  }
25
-
26
- if (arr1[i] === arr2[i]) {
27
- matches++;
25
+ },
26
+ );
27
+ const sortedArr2 = arr2.map((item) => JSON.stringify(item)).sort().map(
28
+ (item) => {
29
+ try {
30
+ return JSON.parse(item);
31
+ } catch (e) {
32
+ return undefined;
28
33
  }
34
+ },
35
+ );
36
+
37
+ const maxLength = Math.min(arr1.length, arr2.length);
38
+ for (let i = 0; i < maxLength; i++) {
39
+ fields++;
40
+ if (Array.isArray(sortedArr1[i]) && Array.isArray(sortedArr2[i])) {
41
+ const subData = compareArrays(
42
+ sortedArr1[i],
43
+ sortedArr2[i],
44
+ max_depth - 1,
45
+ );
46
+ fields += subData[0] - 1; // Subtract 1 for the index itself
47
+ matches += subData[1];
48
+ } else if (
49
+ (typeof sortedArr1[i] == "object" && sortedArr1[i]) &&
50
+ (typeof sortedArr2[i] == "object" && sortedArr2[i])
51
+ ) {
52
+ const subData = compareDatasets(
53
+ sortedArr1[i] as FPDataSet,
54
+ sortedArr2[i] as FPDataSet,
55
+ max_depth - 1,
56
+ );
57
+ fields += subData[0] - 1; // Subtract 1 for the index itself
58
+ matches += subData[1];
59
+ }
60
+
61
+ if (arr1[i] === arr2[i]) {
62
+ matches++;
29
63
  }
30
64
  }
31
65
  return [fields, matches];
32
66
  }
33
67
 
34
- function compareDatasets(data1: FPDataSet, data2: FPDataSet): [number, number] {
68
+ export function compareDatasets(
69
+ data1: FPDataSet,
70
+ data2: FPDataSet,
71
+ max_depth: number = 5,
72
+ ): [number, number] {
35
73
  let fields = 0;
36
74
  let matches = 0;
75
+
76
+ // Ensure max_depth is not exceeded
77
+ if (max_depth <= 0) {
78
+ throw new Error("Max depth exceeded");
79
+ }
80
+
37
81
  for (const key in data1) {
38
82
  if (data1[key] !== undefined && data2[key] !== undefined) {
39
83
  fields++;
@@ -41,13 +85,15 @@ function compareDatasets(data1: FPDataSet, data2: FPDataSet): [number, number] {
41
85
  (typeof data1[key] == "object" && data1[key]) &&
42
86
  (typeof data2[key] == "object" && data2[key])
43
87
  ) {
44
- const subData = compareDatasets(data1[key] as FPDataSet, data2[key] as FPDataSet);
88
+ const subData = compareDatasets(
89
+ data1[key] as FPDataSet,
90
+ data2[key] as FPDataSet,
91
+ max_depth - 1,
92
+ );
45
93
  fields += subData[0] - 1; // Subtract 1 for the key itself
46
94
  matches += subData[1];
47
- }
48
-
49
- else if (Array.isArray(data1[key]) && Array.isArray(data2[key])) {
50
- const subData = compareArrays(data1[key], data2[key]);
95
+ } else if (Array.isArray(data1[key]) && Array.isArray(data2[key])) {
96
+ const subData = compareArrays(data1[key], data2[key], max_depth - 1);
51
97
  fields += subData[0] - 1; // Subtract 1 for the key itself
52
98
  matches += subData[1];
53
99
  }
@@ -60,26 +106,34 @@ function compareDatasets(data1: FPDataSet, data2: FPDataSet): [number, number] {
60
106
  return [fields, matches];
61
107
  }
62
108
 
63
- export function calculateConfidence(data1: FPDataSet, data2: FPDataSet): number {
64
- // Compare how many fields are the same in both datasets
65
- const [fields, matches] = compareDatasets(data1, data2);
109
+ export function calculateConfidence(
110
+ data1: FPDataSet,
111
+ data2: FPDataSet,
112
+ ): number {
113
+ try {
114
+ // Compare how many fields are the same in both datasets
115
+ const [fields, matches] = compareDatasets(data1, data2);
66
116
 
67
- if (fields === 0 || matches === 0) {
68
- return 0;
69
- }
117
+ if (fields === 0 || matches === 0) {
118
+ return 0;
119
+ }
70
120
 
71
- // Calculate the hash for each user data
72
- const hash1 = getHash(JSON.stringify(data1));
73
- const hash2 = getHash(JSON.stringify(data2));
121
+ // Calculate the hash for each user data
122
+ const hash1 = getHash(JSON.stringify(data1));
123
+ const hash2 = getHash(JSON.stringify(data2));
74
124
 
75
- // Compare the hashes to get their difference
76
- const differenceScore = compareHashes(hash1, hash2);
125
+ // Compare the hashes to get their difference
126
+ const differenceScore = compareHashes(hash1, hash2);
77
127
 
78
- const inverseMatchScore = 1 - (matches / fields);
79
- const x = 1.3 * differenceScore * inverseMatchScore
80
- if (inverseMatchScore === 0 || differenceScore === 0) {
81
- return 100;
128
+ const inverseMatchScore = 1 - (matches / fields);
129
+ const x = 1.3 * differenceScore * inverseMatchScore;
130
+ if (inverseMatchScore === 0 || differenceScore === 0) {
131
+ return 100;
132
+ }
133
+ const confidenceScore = 100 / (1 + Math.E ** (-4.5 + (0.3 * x)));
134
+ return confidenceScore;
135
+ } catch (error) {
136
+ console.error("Error calculating confidence:", error);
137
+ return 0; // Return 0 if an error occurs during comparison
82
138
  }
83
- const confidenceScore = 100 / (1 + Math.E ** (-4.5 + (0.3 * x)));
84
- return confidenceScore;
85
- }
139
+ }
package/src/main.js CHANGED
@@ -1,5 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.calculateConfidence = void 0;
3
+ exports.calculateConfidence = exports.compareDatasets = exports.compareArrays = void 0;
4
4
  const confidence_1 = require("./libs/confidence");
5
+ Object.defineProperty(exports, "compareArrays", { enumerable: true, get: function () { return confidence_1.compareArrays; } });
6
+ Object.defineProperty(exports, "compareDatasets", { enumerable: true, get: function () { return confidence_1.compareDatasets; } });
5
7
  Object.defineProperty(exports, "calculateConfidence", { enumerable: true, get: function () { return confidence_1.calculateConfidence; } });
package/src/main.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import { FPUserDataSet, FPDataSet } from "./types/data";
2
- import { calculateConfidence } from "./libs/confidence";
2
+ import { compareArrays, compareDatasets, calculateConfidence } from "./libs/confidence";
3
3
 
4
- export { type FPUserDataSet, type FPDataSet, calculateConfidence };
4
+ export { type FPUserDataSet, type FPDataSet, compareArrays, compareDatasets, calculateConfidence };
@@ -0,0 +1,74 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { compareArrays, compareDatasets } from '../src/libs/confidence';
3
+
4
+ describe('Array Comparison', () => {
5
+ it('should compare two identical arrays', () => {
6
+ const arr1 = [1, 2, 3];
7
+ const arr2 = [1, 2, 3];
8
+ const result = compareArrays(arr1, arr2);
9
+ console.log('Result:', result);
10
+ expect(result).toEqual([3, 3]); // 3 fields, 3 matches
11
+ });
12
+
13
+ it('should compare two different arrays', () => {
14
+ const arr1 = [1, 2, 3];
15
+ const arr2 = [3, 1, 4];
16
+ const result = compareArrays(arr1, arr2);
17
+ console.log('Result:', result);
18
+ expect(result).toEqual([3, 0]); // 3 fields, 0 matches
19
+ });
20
+
21
+ it('should handle nested arrays', () => {
22
+ const arr1 = [1, [2, 3], 4];
23
+ const arr2 = [1, [2, 3], 5];
24
+ const result = compareArrays(arr1, arr2);
25
+ console.log('Result:', result);
26
+ expect(result).toEqual([4, 3]); // 4 fields, 3 matches
27
+ });
28
+
29
+ it('should handle empty arrays', () => {
30
+ const arr1: any[] = [];
31
+ const arr2: any[] = [];
32
+ const result = compareArrays(arr1, arr2);
33
+ console.log('Result:', result);
34
+ expect(result).toEqual([0, 0]); // 0 fields, 0 matches
35
+ });
36
+
37
+ it('should handle arrays with different lengths', () => {
38
+ const arr1 = [1, 2, 3];
39
+ const arr2 = [1, 2];
40
+ const result = compareArrays(arr1, arr2);
41
+ console.log('Result:', result);
42
+ expect(result).toEqual([2, 2]); // 2 fields, 2 matches
43
+ });
44
+
45
+ it('should handle arrays with undefined values', () => {
46
+ const arr1 = [1, undefined, 3];
47
+ const arr2 = [1, 2, 3];
48
+ const result = compareArrays(arr1, arr2);
49
+ console.log('Result:', result);
50
+ expect(result).toEqual([3, 2]); // 3 fields, 2 matches
51
+ });
52
+
53
+ it('should handle nested empty arrays', () => {
54
+ const arr1 = [1, [], [[], []], 3];
55
+ const arr2 = [1, [2], [[], []], 3];
56
+ const result = compareArrays(arr1, arr2);
57
+ console.log('Result:', result);
58
+ expect(result).toEqual([3, 2]); // 3 fields, 2 matches
59
+ });
60
+
61
+ it('should handle arrays of objects', () => {
62
+ const arr1 = [{ a: 1 }, { b: 2 }];
63
+ const arr2 = [{ a: 1 }, { b: 3 }];
64
+ const result = compareArrays(arr1, arr2);
65
+ console.log('Result:', result);
66
+ expect(result).toEqual([2, 1]); // 2 fields, 1 matches
67
+ })
68
+
69
+ it('should throw an error for max depth exceeded', () => {
70
+ const arr1 = [1, [2, [3, [4, [5, [6]]]]]];
71
+ const arr2 = [1, [2, [3, [4, [5, [6]]]]]];
72
+ expect(() => compareArrays(arr1, arr2, 0)).toThrow('Max depth exceeded');
73
+ });
74
+ });