Metadata-Version: 2.4
Name: bytecheck
Version: 1.0.0
Summary: Byte-level file/text comparison and verification library built on adamlibrary's C extension modules
Home-page: https://codeberg.org/Zamanhuseyinli/bytecheck
License: GPL-3.0-or-later
Project-URL: Repository, https://codeberg.org/Zamanhuseyinli/bytecheck
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: adamlibrary>=1.7.1
Dynamic: home-page
Dynamic: license-file
Dynamic: requires-python

# bytecheck

A small library for byte-level comparison and verification between
two files or byte sequences, built on top of
[adamlibrary](https://codeberg.org/Zamanhuseyinli/Adam-cpython/)'s C
extension modules.

This is meant to be used as a library first. Importing `bytecheck`
doesn't parse argv or touch stdin - the CLI is just a thin optional
layer on top.

## Install

```bash
pip install -e .
```

## Library usage

```python
import bytecheck

data_a = open("file1.bin", "rb").read()
data_b = open("file2.bin", "rb").read()

result = bytecheck.verify(data_a, data_b)
print(result["match_ratio"])       # e.g. 85.71
print(result["identical"])          # True/False
print(result["mismatched_offsets"]) # list of byte offsets that differ

# Convenience wrappers
bytecheck.is_identical(data_a, data_b)
bytecheck.match_ratio(data_a, data_b)
```

`verify()` returns a plain dict:

| Key | Meaning |
|---|---|
| `size_a` / `size_b` | length of each input in bytes |
| `chunk_size` | comparison chunk size used |
| `total_chunks` | number of chunks compared |
| `matching_chunks` / `mismatched_chunks` | counts |
| `match_ratio` | percentage of matching chunks |
| `mismatched_offsets` | byte offsets where chunks differed |
| `identical` | True if both inputs match exactly |

## Optional CLI

Installing this package also registers a `bytecheck` console script,
and the package can be run directly as a module:

```bash
bytecheck file1.bin file2.bin
python -m bytecheck file1.bin file2.bin --chunk-size 16
python -m bytecheck --text "hello world" --text2 "hello worle"
python -m bytecheck file1.bin file2.bin --quiet   # just IDENTICAL/DIFFERENT + exit code
```

CLI flags:

| Flag | Description |
|---|---|
| `file_a`, `file_b` | files to compare |
| `--text`, `--text2` | compare text directly instead of files |
| `--chunk-size N` | comparison chunk size in bytes (default: 8) |
| `--quiet` | only print IDENTICAL/DIFFERENT, exit code 0/1 |

## C backend usage

| Module | adamlibrary function used | Purpose |
|---|---|---|
| `bytecheck.core` | `adam.memcpy` | copies each input through the C extension before comparison |
| `bytecheck.core` | `datasetname.memcmp` | byte-for-byte chunk comparison |

Note: the binding of `datasetname.memcmp` takes its arguments as C
strings, which cannot contain an embedded null byte. Real binary data
can contain `0x00`, so each null byte is remapped to `0x01` on both
sides before comparing chunks. This is a simple workaround, not a
perfect one - null support may be added to adamlibrary itself in the
future, since this is one of the modules in the adamlibrary
infrastructure. A genuine `0x00` vs `0x01` difference at the same
offset can be masked by the remap, but that's an acceptable trade-off
for a spot check of similarity between two byte streams.

