devicer.js 1.0.8 → 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.8",
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,35 +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
- } else if (
16
- (typeof arr1[i] == "object" && arr1[i]) &&
17
- (typeof arr2[i] == "object" && arr2[i])
18
- ) {
19
- const subData = compareDatasets(arr1[i] as FPDataSet, arr2[i] as FPDataSet);
20
- fields += subData[0] - 1; // Subtract 1 for the index itself
21
- matches += subData[1];
22
- } else if (arr1[i] === arr2[i]) {
23
- matches++;
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
+ );
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;
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++;
25
63
  }
26
64
  }
27
65
  return [fields, matches];
28
66
  }
29
67
 
30
- 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] {
31
73
  let fields = 0;
32
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
+
33
81
  for (const key in data1) {
34
82
  if (data1[key] !== undefined && data2[key] !== undefined) {
35
83
  fields++;
@@ -37,13 +85,15 @@ function compareDatasets(data1: FPDataSet, data2: FPDataSet): [number, number] {
37
85
  (typeof data1[key] == "object" && data1[key]) &&
38
86
  (typeof data2[key] == "object" && data2[key])
39
87
  ) {
40
- 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
+ );
41
93
  fields += subData[0] - 1; // Subtract 1 for the key itself
42
94
  matches += subData[1];
43
- }
44
-
45
- else if (Array.isArray(data1[key]) && Array.isArray(data2[key])) {
46
- 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);
47
97
  fields += subData[0] - 1; // Subtract 1 for the key itself
48
98
  matches += subData[1];
49
99
  }
@@ -56,26 +106,34 @@ function compareDatasets(data1: FPDataSet, data2: FPDataSet): [number, number] {
56
106
  return [fields, matches];
57
107
  }
58
108
 
59
- export function calculateConfidence(data1: FPDataSet, data2: FPDataSet): number {
60
- // Compare how many fields are the same in both datasets
61
- 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);
62
116
 
63
- if (fields === 0 || matches === 0) {
64
- return 0;
65
- }
117
+ if (fields === 0 || matches === 0) {
118
+ return 0;
119
+ }
66
120
 
67
- // Calculate the hash for each user data
68
- const hash1 = getHash(JSON.stringify(data1));
69
- 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));
70
124
 
71
- // Compare the hashes to get their difference
72
- const differenceScore = compareHashes(hash1, hash2);
125
+ // Compare the hashes to get their difference
126
+ const differenceScore = compareHashes(hash1, hash2);
73
127
 
74
- const inverseMatchScore = 1 - (matches / fields);
75
- const x = 1.3 * differenceScore * inverseMatchScore
76
- if (inverseMatchScore === 0 || differenceScore === 0) {
77
- 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
78
138
  }
79
- const confidenceScore = 100 / (1 + Math.E ** (-4.5 + (0.3 * x)));
80
- return confidenceScore;
81
- }
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
+ });