Similar versions: surface-overlap metric + endpoint + UI panel
Ranks catalogued engine versions by how much of their CMC_* surface they share,
which (unlike a binary fuzzy hash) stays meaningful across compilers — the golden
pair PIKLIB8/MSVC6 vs bloomoodll/MSVC8 scores 85%.
- similarity.py: jaccard, surface_similarity (per-axis + pooled overall),
fuzzy_similarity (ssdeep via ppdeep, secondary signal)
- service.similar_snapshots + GET /snapshots/{id}/similar?min=N (SimilarHit)
- UI: "Podobne wersje" panel in the snapshot browser (overlap bar + ⇄ diff)
- tests: 6 new (jaccard, identical/disjoint, golden pair 0<x<100, fuzzy,
endpoint + min filter) -> 28/28
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -273,6 +273,9 @@ async function browse(id) {
|
||||
];
|
||||
out.innerHTML = "";
|
||||
out.append(el("div", { class: "diff-head" }, "Przegląd: ", el("b", {}, `${snap.binary_name} [${snap.engine}/${snap.compiler}]`)));
|
||||
const simBox = el("div", { class: "similar" });
|
||||
out.append(simBox);
|
||||
loadSimilar(id, simBox);
|
||||
const filter = el("input", { class: "owner browse-filter", placeholder: "filtruj…", oninput: () => render() });
|
||||
const tabbar = el("div", {});
|
||||
const list = el("div", {});
|
||||
@@ -292,6 +295,27 @@ async function browse(id) {
|
||||
render();
|
||||
}
|
||||
|
||||
async function loadSimilar(targetId, box) {
|
||||
let hits;
|
||||
try { hits = await jget("/snapshots/" + targetId + "/similar"); }
|
||||
catch { return; } // endpoint absent / single-snapshot catalog — just show nothing
|
||||
if (!hits.length) return;
|
||||
box.append(el("div", { class: "similar-title" }, "Podobne wersje (overlap powierzchni)"));
|
||||
for (const h of hits.slice(0, 6)) {
|
||||
const s = h.snapshot;
|
||||
const bar = el("span", { class: "simbar" },
|
||||
el("span", { class: "simfill", style: "width:" + h.overall + "%" }));
|
||||
box.append(el("div", { class: "simrow" },
|
||||
el("span", { class: "simscore" }, h.overall + "%"),
|
||||
bar,
|
||||
el("span", { class: "simname", title: "przejrzyj", onclick: () => browse(s.id) },
|
||||
`${s.binary_name} [${s.engine || "?"}]`),
|
||||
h.fuzzy != null ? el("span", { class: "simfuzzy", title: "ssdeep binarki" }, "fuzzy " + h.fuzzy) : null,
|
||||
el("span", { class: "simdiff", title: "porównaj tę wersję z aktualną",
|
||||
onclick: () => { state.a = targetId; state.b = s.id; refreshSelection(); compare(); } }, "⇄ diff")));
|
||||
}
|
||||
}
|
||||
|
||||
// --- boot -------------------------------------------------------------------------------------
|
||||
$("compare").addEventListener("click", compare);
|
||||
$("owner").addEventListener("keydown", (e) => { if (e.key === "Enter") compare(); });
|
||||
|
||||
Reference in New Issue
Block a user