Files
nexus/internal/leviathan/analysis/overview.go
T
2026-06-16 11:51:07 +01:00

89 lines
2.1 KiB
Go

package analysis
import (
"github.com/andydixon/nexus/internal/leviathan/document"
)
// Overview returns a compact first-pass report intended for both UI
// surfaces. It favours fast, bounded summaries over exhaustive output.
func Overview(d *document.Document) (map[string]any, error) {
size := d.Size()
hashes, err := Hashes(d, 0, -1)
if err != nil {
return nil, err
}
entropy, err := Entropy(d, 0, min64(size, 8<<20), 4096, 0)
if err != nil {
return nil, err
}
stringsOut, err := ExtractStrings(d, 0, min64(size, 16<<20), 4, []string{"ascii", "utf16le", "utf16be"}, 5000)
if err != nil {
return nil, err
}
iocs, err := ExtractIOCs(d, 0, min64(size, 16<<20), 5)
if err != nil {
return nil, err
}
carves, err := Carve(d, 0, min64(size, 64<<20), 128)
if err != nil {
return nil, err
}
return map[string]any{
"name": d.Name(),
"size": size,
"hashes": hashes,
"entropy": overviewEntropy(entropy),
"strings": overviewStrings(stringsOut),
"iocs": iocs["totals"],
"carve": overviewCarve(carves),
"limits": map[string]any{
"entropyBytes": min64(size, 8<<20),
"stringsBytes": min64(size, 16<<20),
"iocBytes": min64(size, 16<<20),
"carveBytes": min64(size, 64<<20),
},
}, nil
}
func overviewEntropy(in map[string]any) map[string]any {
return map[string]any{
"windowSize": in["windowSize"],
"step": in["step"],
"mean": in["mean"],
"min": in["min"],
"max": in["max"],
"highCount": in["highCount"],
}
}
func overviewStrings(items []map[string]any) map[string]any {
counts := map[string]int{}
for _, item := range items {
if enc, ok := item["encoding"].(string); ok {
counts[enc]++
}
}
return map[string]any{
"total": len(items),
"byEncoding": counts,
}
}
func overviewCarve(items []map[string]any) map[string]any {
counts := map[string]int{}
valid := 0
for _, item := range items {
if kind, ok := item["kind"].(string); ok {
counts[kind]++
}
if status, ok := item["status"].(string); ok && status == "valid" {
valid++
}
}
return map[string]any{
"total": len(items),
"valid": valid,
"byKind": counts,
}
}