decayfmt-py
A file format where decay is a first-class property: every open permanently corrupts the file.
This is the Python binding for the decayfmt format. Install it with pip install decayfmt-py; the module you import is decayfmt. Encode a clean file once, then let it decay one open at a time. Each open replaces a random slice of the payload with noise and writes it back to disk. A corrupted file cannot be restored from its own contents. The header is immutable; only the payload decays.
The binding wraps the same Rust library the CLI uses, so behavior, statistics, and errors are identical.
Install
pip install decayfmt-py
Requires Python 3.11+. Wheels are built from Rust via PyO3 (abi3), so no Rust toolchain is needed at install time.
Quickstart
import decayfmt
# Encode a clean text file. The extension carries the type and the decay rate:
# `tdcy<x>` = text, `idcy<x>` = image, x = instability (higher decays faster).
decayfmt.encode_file("notes.txt", "notes.tdcy5")
# Open it five times. Each open permanently corrupts the file on disk.
for _ in range(5):
kind, dims, data = decayfmt.decay_file("notes.tdcy5")
print(data[16:].decode("utf-8", errors="replace"))
# Work purely in memory instead: each call decays a fresh copy of the bytes.
data = b"the quick brown fox jumps over the lazy dog"
for _ in range(8):
data = decayfmt.corrupt_bytes(data, 1.0, "text")
print(data.decode("utf-8", errors="replace"))
# Zero-copy decay of a mutable buffer:
buf = bytearray(b"some text that will decay")
decayfmt.corrupt_in_place(buf, 10.0, "text")
Corruption probability per eligible byte is p = 1 - exp(-x / 10): x = 1 corrupts roughly 9.5% per open, x = 10 roughly 63%. Image corruption touches only the R, G, and B channels, so transparency (alpha) is never damaged. Text corruption replaces bytes with printable ASCII, so at high x it can break UTF-8 sequences.
API
| Function | Returns | Notes |
|---|---|---|
corrupt_bytes(data, x, kind) -> bytes |
corrupted copy | kind is "image" or "text"; immutable bytes are copied once |
corrupt_in_place(buffer, x, kind) -> None |
— | mutates a bytearray in place, no copy; for a memoryview use bytearray(mv) |
encode_file(source_path, output_path) -> None |
— | same as the CLI encode; output name decides type and x |
encode_bytes(source, output_path) -> None |
— | encodes in-memory bytes (image formats decoded, text validated as UTF-8) |
decay_file(path) -> (kind, dims, bytes) |
type label, (w, h) or None, full file bytes |
permanently corrupts the file on disk, no display |
parse_filename(name) -> (kind, x) |
— | "photo.idcy3" → ("image", 3.0) |
read_header(data) -> (kind, dims) |
— | reads the 16-byte header |
write_header(kind, width, height) -> bytes |
16-byte header | image requires width and height |
decayfmt.__version__ |
version string | — |
x is not clamped: x <= 0 corrupts nothing, and large x approaches corrupting every byte. The CLI reads x from filenames as a positive integer; the API accepts any float.
Errors
Failures raise built-in exceptions with the exact message the CLI would print:
OSErrorfor filesystem read/write failures (includes the OS error string).PermissionErrorfor a read-only target, where the corrupted payload cannot be written back.ValueErrorfor everything else: wrong magic bytes, unknown version, bad filename convention, invalid UTF-8 at encode, undecodable image, and so on.
Threading
The GIL is released while corruption, encoding, and file operations run, and large payloads (≥ 1 MiB) are corrupted in parallel across cores. Corruption is drawn from generators seeded by operating system entropy, so the corruption sequence cannot be replayed.
Image formats
encode_file / encode_bytes accept whatever the underlying Rust image library decodes: PNG, JPEG, GIF, WebP, TIFF, QOI, BMP, DDS, EXR, HDR, ICO, PNM, TGA, and farbfeld. Images are stored as raw RGBA, so any format the library can decode becomes a decaying image.
License
MIT. Same license as the decayfmt project.
Metadata
Release files for decayfmt-py 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Actions Reset | |||
|---|---|---|---|---|
| decayfmt_py-0.2.0-cp311-abi3-win_amd64.whl | CPython 3.11 | abi3 | Windows x86-64 | Details for decayfmt_py-0.2.0-cp311-abi3-win_amd64.whl |
| decayfmt_py-0.2.0-cp311-abi3-manylinux_2_34_x86_64.whl | CPython 3.11 | abi3 | Linux glibc 2.34+ x86-64 | Details for decayfmt_py-0.2.0-cp311-abi3-manylinux_2_34_x86_64.whl |
| decayfmt_py-0.2.0-cp311-abi3-manylinux_2_34_aarch64.whl | CPython 3.11 | abi3 | Linux glibc 2.34+ ARM64 | Details for decayfmt_py-0.2.0-cp311-abi3-manylinux_2_34_aarch64.whl |
| decayfmt_py-0.2.0-cp311-abi3-macosx_11_0_arm64.whl | CPython 3.11 | abi3 | macOS 11.0+ ARM64 | Details for decayfmt_py-0.2.0-cp311-abi3-macosx_11_0_arm64.whl |
Total release size: 5.3 MB
Release files / decayfmt_py-0.2.0-cp311-abi3-win_amd64.whl
| Download URL | decayfmt_py-0.2.0-cp311-abi3-win_amd64.whl |
|---|---|
| Size | 1.3 MB |
| Tags | CPython 3.11 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
bc0f18a9cc134ca2307e1a8e0185abbb9be44ee5cd6a05810eafe39b4235bba4
|
|
BLAKE2b-256 checksum How to use checksums |
530fb890999ce31a2997ea6ddb4c08a68ba7edef86d564146901c9a5b112cd2d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.15.0
|
Release files / decayfmt_py-0.2.0-cp311-abi3-manylinux_2_34_x86_64.whl
| Download URL | decayfmt_py-0.2.0-cp311-abi3-manylinux_2_34_x86_64.whl |
|---|---|
| Size | 1.4 MB |
| Tags | CPython 3.11 Linux glibc 2.34+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
54665b75598fde7061af917a7bcbf14023cbcfe79ec648c076a1a2ded881831b
|
|
BLAKE2b-256 checksum How to use checksums |
9da61165072ca3c30de28a6cad3190f6e86f352cc06d198a54dd19d0bc497582
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.15.0
|
Release files / decayfmt_py-0.2.0-cp311-abi3-manylinux_2_34_aarch64.whl
| Download URL | decayfmt_py-0.2.0-cp311-abi3-manylinux_2_34_aarch64.whl |
|---|---|
| Size | 1.3 MB |
| Tags | CPython 3.11 Linux glibc 2.34+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
d9e6439a2debc22dcfd5ae531ee72a7ddf511150796d296a6e8ae7e894d0e6f6
|
|
BLAKE2b-256 checksum How to use checksums |
cc2c5624df904c41fddbd67c4725732ba5e42e19d794108bd1dfe3b774973902
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.15.0
|
Release files / decayfmt_py-0.2.0-cp311-abi3-macosx_11_0_arm64.whl
| Download URL | decayfmt_py-0.2.0-cp311-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.3 MB |
| Tags | CPython 3.11 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
712213859651ed96417cfe5c45d3cbcfdded32e111f4e65cb6819c6547d7091c
|
|
BLAKE2b-256 checksum How to use checksums |
bef5bd6f691ec299090839a3c786b6f8f870299a38df57331c33dd8c91a509df
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.15.0
|
Security for decayfmt-py 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.