Repair benchmark

Repair benchmark

A fixed, downloadable corpus of corrupted files. Our engine's results on every one of them, published with the method — including the ones it fails.

Corpus
30 files
Opens after repair
23 / 30
No output
5 / 30
Engine
v1.2.4 · 2026-09-12

“Opens” is the strictest cell we could define: the output must decode completely, as its original format, with a stock third-party decoder — not with our own validator. The corpus is synthetic and regenerable from a seed, so anyone can reproduce this table or run another tool against the same bytes.

Results

Format × corruption. Hover a cell for the engine's own notes.

FormatTruncated at 60%Header zeroed (64 B)Garbage prefix (4 KiB)Mid-file zeroed (4 KiB)Wrong extensionOpens
JPEG
StructuralOpens6 ms
FailedDoes not open1 ms
ExtractedOpens4 ms
CleanOpens1 ms
CleanOpens0 ms
4 / 5
PNG
FailedDoes not open2 ms
FailedDoes not open3 ms
StructuralOpens2 ms
ExtractedDoes not open4 ms
CleanOpens0 ms
2 / 5
GIF
StructuralOpens1 ms
FailedDoes not open0 ms
StructuralOpens0 ms
StructuralOpens0 ms
CleanOpens0 ms
4 / 5
MP4
StructuralOpens0 ms
FailedDoes not open1 ms
ExtractedOpens2 ms
CleanOpens0 ms
CleanOpens0 ms
4 / 5
PDF
StructuralOpens2 ms
StructuralOpens4 ms
CleanOpens1 ms
ExtractedOpens3 ms
CleanOpens1 ms
5 / 5
DOCX
StructuralOpens0 ms
StructuralOpens0 ms
CleanOpens0 ms
ExtractedDoes not open1 ms
CleanOpens0 ms
4 / 5
Opens5 / 62 / 66 / 64 / 66 / 623 / 30
Clean
The engine judged the input already valid and left it alone.
Structural
Tier 1 — a format plugin rewrote the file structure in place.
Extracted
Tier 2/3 — valid file(s) were carved out of the damaged container.
Salvage
Tier 4 — only clearly-labelled, low-confidence salvage artifacts (e.g. extracted text).
Failed
No tier produced any output.

Same corpus, other tools

Files opened out of 5 per format, under the identical rule. We publish a competitor number only after running that tool by hand against the downloadable corpus; until then the cell says so.

FormatDataRecover PrountruncMP4/MOV onlyStellar Repair for Videovideo onlyDisk Drillrecovery suite
JPEG4 / 5not yet measurednot yet measurednot yet measured
PNG2 / 5not yet measurednot yet measurednot yet measured
GIF4 / 5not yet measurednot yet measurednot yet measured
MP44 / 5not yet measurednot yet measurednot yet measured
PDF5 / 5not yet measurednot yet measurednot yet measured
DOCX4 / 5not yet measurednot yet measurednot yet measured

Methodology

Corpus generation

Six clean sources are synthesized in code from a fixed seed (0x5eedda7a20260911): JPEG, PNG and GIF are rendered images; the MP4 is a complete ISOBMFF container with real sample tables and 60 length-prefixed samples; the PDF is 24 pages with a correct xref; the DOCX has the standard OOXML parts plus an embedded PNG. Each source is put through the five corruption operators below, giving 30 files. Re-running the generator reproduces the same bytes and SHA-256s — they are listed in manifest.json.

Run environment

Engine
v1.2.4 (e43f239)
Date
2026-09-12T05:12:24Z
Machine
Apple M5 Max · macos/aarch64
Build
release, single run

Corruption types

Truncated at 60%

The file is cut at 60% of its length. The tail — and for some formats the index that lives there — is gone for good.

Header zeroed (64 B)

The first 64 bytes are overwritten with zeros, destroying the magic number and the start of the header.

Garbage prefix (4 KiB)

4 KiB of seeded random bytes are prepended; every byte of the original file is still present, just not at offset 0.

Mid-file zeroed (4 KiB)

A 4 KiB block centred on the midpoint is overwritten with zeros — the classic bad-sector pattern.

Wrong extension

The bytes are untouched but the file carries the wrong extension, so extension-based tools pick the wrong decoder.

How results are judged

  • Corpus: 6 synthetic clean sources (JPEG/PNG/GIF rendered with the `image` crate; MP4, PDF and DOCX built in code) x 5 corruption operators = 30 files, generated from a fixed seed. Re-running `gen` reproduces the same bytes and sha256s.
  • Engine path: `RepairEngine::repair_file` — the same tiered cascade (Tier 1 plugin repair, Tier 2 deep scan, Tier 3 extraction, Tier 4 salvage) the desktop app calls through the privileged service. Tier 1 plugins run in-process here; the app additionally wraps single-plugin repairs in a sandboxed worker, which changes isolation, not output.
  • Assessment: `RepairEngine::assess` on the bytes, routed by the file's on-disk extension (the same routing the app uses); the dedicated format plugin's verdict takes precedence over extraction-only plugins.
  • Tier reported: clean = engine judged input already valid; structural = Tier 1 rewrote the file; partial = Tier 2/3 carved valid file(s) out; salvage = only labelled low-confidence salvage artifacts; failed = nothing produced.
  • "Opens" = the primary output decodes as the ORIGINAL format with an independent stock decoder: jpeg-decoder (strict), the png/gif crates, lopdf (all pages' content streams readable), the zip crate (every member inflates with a valid CRC, mandatory OOXML parts present) and an in-house ISOBMFF box walk (boxes tile the file, ftyp first, moov+mdat present, all chunk offsets in-file). Any decoder error counts as "does not open".
  • Duration = wall-clock for assess + repair_file on one file, single run, release build, no warm-up. Treat it as an order of magnitude, not a measurement.
  • Expected-outcome class describes the theoretical ceiling for the corruption (bytes intact / header rebuild / partial content), not a prediction of any tool's result.

What this does not show

  • It is a synthetic corpus. Real camera and phone failures — a GoPro that lost power mid-recording, an iPhone HEVC file with a missing moov, a DSLR card with interleaved fragments — are messier than five clean operators. Good numbers here are necessary, not sufficient.
  • “Opens” is not “looks right.” A JPEG or MP4 with 4 KiB zeroed in the middle of its payload can decode without a single error and still show a band of garbage. Those files are marked Clean because no decoder can tell the difference — and neither can we.
  • The failures are real. GIF and header-destroyed images are weak spots in this engine version, and the table says so. We would rather publish a gap than a cherry-picked corpus.
  • Competitor columns are pending. We have not yet run untrunc, Stellar Repair for Video or Disk Drill against this corpus. Nothing in those columns is estimated or inferred.
  • Timings are indicative only. Single run, no warm-up, small files. They tell you the repair is fast, not how fast.

Reproduce it

The corpus is published at /benchmark/corpus.zip (about 2 MB: 6 clean sources, 30 corrupted files, and the manifest with every SHA-256). Point any repair tool at the corrupt/ folder and count what opens under the same rule.

# regenerate the corpus (byte-identical) and run the engine
cargo run --release -p datarecover-pro-bench -- gen bench/corpus
cargo run --release -p datarecover-pro-bench -- run bench/corpus --out bench/results.json

Try it on your own files.

Scan and preview for free. Repair runs locally, in a sandbox, and you see what opens before you pay.