@cloudglides/veil 0.1.0 → 0.1.1
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/.github/workflows/build-on-tag.yml +2 -0
- package/.github/workflows/deploy-pages.yml +73 -0
- package/README.md +190 -0
- package/example/index.html +16 -22
- package/example/veil_core.d.ts +71 -0
- package/example/veil_core.js +370 -0
- package/example/veil_core_bg.wasm +0 -0
- package/example/veil_core_bg.wasm.d.ts +20 -0
- package/package.json +1 -1
- package/src/entropy/approximate.ts +3 -2
- package/src/entropy/complexity.ts +3 -2
- package/src/entropy/distribution.ts +3 -2
- package/src/entropy/spectral.ts +3 -2
- package/src/index.ts +92 -42
- package/src/stability.ts +405 -0
- package/src/tamper.ts +207 -0
- package/src/types.ts +11 -2
- package/src/wasm-loader.ts +32 -2
- package/tsup.config.ts +20 -14
- package/veil-core/src/lib.rs +3 -0
- package/veil-core/src/similarity.rs +67 -0
package/tsup.config.ts
CHANGED
|
@@ -10,26 +10,32 @@ export default defineConfig({
|
|
|
10
10
|
clean: true,
|
|
11
11
|
shims: true,
|
|
12
12
|
outDir: "dist",
|
|
13
|
-
external: ["./veil_core.js"],
|
|
13
|
+
external: ["./veil_core.js", "../veil-core/pkg/veil_core.js"],
|
|
14
|
+
noExternal: [],
|
|
15
|
+
splitting: true,
|
|
14
16
|
onSuccess: async () => {
|
|
15
17
|
const srcWasmDir = resolve("veil-core/pkg");
|
|
16
18
|
const distDir = resolve("dist");
|
|
19
|
+
const exampleDir = resolve("example");
|
|
17
20
|
|
|
18
21
|
await mkdir(distDir, { recursive: true });
|
|
22
|
+
await mkdir(exampleDir, { recursive: true });
|
|
19
23
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
for (const dir of [distDir, exampleDir]) {
|
|
25
|
+
await cp(`${srcWasmDir}/veil_core_bg.wasm`, `${dir}/veil_core_bg.wasm`);
|
|
26
|
+
await cp(`${srcWasmDir}/veil_core.js`, `${dir}/veil_core.js`);
|
|
27
|
+
await cp(`${srcWasmDir}/veil_core.d.ts`, `${dir}/veil_core.d.ts`);
|
|
28
|
+
await cp(
|
|
29
|
+
`${srcWasmDir}/veil_core_bg.wasm.d.ts`,
|
|
30
|
+
`${dir}/veil_core_bg.wasm.d.ts`,
|
|
31
|
+
);
|
|
27
32
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
let wasmContent = readFileSync(`${dir}/veil_core.js`, "utf-8");
|
|
34
|
+
wasmContent = wasmContent.replace(
|
|
35
|
+
/module_or_path = new URL\('veil_core_bg\.wasm', import\.meta\.url\);/g,
|
|
36
|
+
"module_or_path = new URL('veil_core_bg.wasm', import.meta.url).href;",
|
|
37
|
+
);
|
|
38
|
+
writeFileSync(`${dir}/veil_core.js`, wasmContent);
|
|
39
|
+
}
|
|
34
40
|
},
|
|
35
41
|
});
|
package/veil-core/src/lib.rs
CHANGED
|
@@ -3,6 +3,7 @@ use std::usize;
|
|
|
3
3
|
use wasm_bindgen::prelude::*;
|
|
4
4
|
|
|
5
5
|
mod entropy;
|
|
6
|
+
mod similarity;
|
|
6
7
|
|
|
7
8
|
const MURMUR_SEED: u32 = 0x811c9dc5;
|
|
8
9
|
const FNV_PRIME: u32 = 16777619;
|
|
@@ -88,3 +89,5 @@ pub fn approx_entropy(samples: &[f64], m: usize) -> f64 {
|
|
|
88
89
|
pub fn sample_ent(samples: &[f64], m: usize, r: f64) -> f64 {
|
|
89
90
|
entropy::sample_entropy(samples, m, r)
|
|
90
91
|
}
|
|
92
|
+
|
|
93
|
+
pub use similarity::{levenshtein_distance, similarity_score, cosine_similarity};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
pub use wasm_bindgen::prelude::*;
|
|
2
|
+
|
|
3
|
+
#[wasm_bindgen]
|
|
4
|
+
pub fn levenshtein_distance(s1: &str, s2: &str) -> u32 {
|
|
5
|
+
let len1 = s1.len();
|
|
6
|
+
let len2 = s2.len();
|
|
7
|
+
let mut matrix = vec![vec![0u32; len2 + 1]; len1 + 1];
|
|
8
|
+
|
|
9
|
+
for i in 0..=len1 {
|
|
10
|
+
matrix[i][0] = i as u32;
|
|
11
|
+
}
|
|
12
|
+
for j in 0..=len2 {
|
|
13
|
+
matrix[0][j] = j as u32;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let bytes1 = s1.as_bytes();
|
|
17
|
+
let bytes2 = s2.as_bytes();
|
|
18
|
+
|
|
19
|
+
for i in 1..=len1 {
|
|
20
|
+
for j in 1..=len2 {
|
|
21
|
+
let cost = if bytes1[i - 1] == bytes2[j - 1] { 0 } else { 1 };
|
|
22
|
+
matrix[i][j] = std::cmp::min(
|
|
23
|
+
std::cmp::min(matrix[i - 1][j] + 1, matrix[i][j - 1] + 1),
|
|
24
|
+
matrix[i - 1][j - 1] + cost,
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
matrix[len1][len2]
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
#[wasm_bindgen]
|
|
33
|
+
pub fn similarity_score(s1: &str, s2: &str) -> f64 {
|
|
34
|
+
let distance = levenshtein_distance(s1, s2) as f64;
|
|
35
|
+
let max_len = std::cmp::max(s1.len(), s2.len()) as f64;
|
|
36
|
+
if max_len == 0.0 {
|
|
37
|
+
1.0
|
|
38
|
+
} else {
|
|
39
|
+
1.0 - (distance / max_len)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
#[wasm_bindgen]
|
|
44
|
+
pub fn cosine_similarity(v1: &[f64], v2: &[f64]) -> f64 {
|
|
45
|
+
if v1.len() != v2.len() || v1.is_empty() {
|
|
46
|
+
return 0.0;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let mut dot = 0.0;
|
|
50
|
+
let mut mag1 = 0.0;
|
|
51
|
+
let mut mag2 = 0.0;
|
|
52
|
+
|
|
53
|
+
for i in 0..v1.len() {
|
|
54
|
+
dot += v1[i] * v2[i];
|
|
55
|
+
mag1 += v1[i] * v1[i];
|
|
56
|
+
mag2 += v2[i] * v2[i];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
mag1 = mag1.sqrt();
|
|
60
|
+
mag2 = mag2.sqrt();
|
|
61
|
+
|
|
62
|
+
if mag1 == 0.0 || mag2 == 0.0 {
|
|
63
|
+
0.0
|
|
64
|
+
} else {
|
|
65
|
+
dot / (mag1 * mag2)
|
|
66
|
+
}
|
|
67
|
+
}
|