# similar

> **Tool `tools/triage/similar.py`** (program, Triage). How alike two files are, when they are not identical: two versions of an executable, a patched data file, a renamed file, or a library the game links against.

Run it with `./gameframe run similar ARGS` or `python3 tools/triage/similar.py`. [Source on GitHub](https://github.com/tanepiper/game-frame/blob/main/tools/triage/similar.py).

## Its own help

This is the help text in the tool itself, as `./gameframe tool similar` prints it.

```text
How alike two files are, when they are not identical: two versions of an executable, a
patched data file, a renamed file, or a library the game links against.

Usage: similar.py A B                  two files: a score from 0 to 100
       similar.py FILE DIR             every file in DIR that resembles FILE, best first
       similar.py DIR_A DIR_B          each file of DIR_A with its closest file in DIR_B
       options: --min N (default 20)  hide scores below N;  --json

compare_trees.py says whether two files are the same. This tool says how much they share.
It cuts each file into pieces where the content itself says so (a rolling hash over a few
bytes picks the cut points), and hashes each piece. An insertion or a change then moves or
changes only the pieces around it, and the rest still match. The score is the share of bytes
in matching pieces.

Uses:
- which release a copy is closest to, and how much changed between two patches;
- a file that was renamed or moved between versions (DIR_A DIR_B shows it);
- the parts of an executable that are a known library (compare with the library's own build;
  then confirm with the code, re-trace);
- which saves or levels differ only a little, to find the bytes that hold one setting.

The idea is context-triggered piecewise hashing, as in ssdeep. This is GameFrame's own
implementation, and its scores are not ssdeep's. Standard library only.
```

## Named by

Skills: [re-inventory](/skills/re-inventory), [re-format](/skills/re-format).
