Skip to main content

StegaQR

StegaQR embeds a small private payload inside a QR code while preserving the public payload for ordinary QR readers. A trained neural decoder recovers the private data.

The package includes a trained hybrid model, repetition and Hamming error correction, a command line interface, and a Python API. The bundled model carries 100 coded bits. With the default repetition code, it carries up to 4 hidden bytes.

Install

pip install stegaQR

StegaQR supports Python 3.10 through 3.12. PyTorch is installed as a required dependency. Public QR decoding uses pyzbar. Some Linux and macOS environments also need the native ZBar library supplied by the operating system.

Command line

Inspect the bundled model:

stegaqr info

Create a QR code with a public URL and a private four byte identifier:

stegaqr encode --public "https://example.com/p" --message "ID42" --out stego.png

Recover both payloads:

stegaqr decode --image stego.png

The generated image includes a quiet zone and nearest neighbor upscaling for reliable scanning. Use --model PATH to select a different trained checkpoint.

Since 0.2.0 the coded bits are spread over the bit grid by a fixed permutation (--placement interleaved, the default). Images produced with 0.1.0 placed coded bit c on grid cell c; decode them with --placement native. Encoder and decoder must use the same placement.

Python API

from stegaqr import decode_hidden, encode_hidden

image = encode_hidden("https://example.com", b"ID42", device="cpu")
public, hidden, metadata = decode_hidden(image, device="cpu")

assert public == "https://example.com"
assert hidden.rstrip(b"\x00") == b"ID42"

CUDA is used when requested and available. Otherwise the package falls back to CPU.

Both functions accept placement="interleaved" (default) or placement="native" (0.1.0 layout), and placement_seed for the interleaved permutation.

Placement of the error-correction copies

The repetition code tiles its copies, so copy r of message bit j is coded bit r*k + j. With the 0.1.0 native placement on the bundled model's grid, all copies of a message bit under Repetition-5 shared one grid column and failed together under distortion. scripts/eval_ecc_layout.py measures both placements on the same checkpoints, covers, messages, and distortion draws; on five cross-channel models and 1,024 messages each, interleaving removed every repetition-code message failure. See experiments/ecc_layout/RESULTS.md.

Embedding modes

The research implementation supports three trained architectures:

Mode Design Purpose
Segregated One encoder and decoder per color channel Channel fault isolation
Cross-channel Joint RGB encoder and decoder Flexible signal placement
Hybrid Joint RGB model with a QR structure mask Protects finder and control modules

The bundled model uses the hybrid architecture with a mask-aware spatial bit grid and no color calibration branch.

Reported results

The saved experiment matrix contains five seed comparisons for the three modes, capacity studies from 25 to 200 coded bits, error correction comparisons, an architecture ablation, and a classical baseline. The physical pilot recovered the public and private payloads from all 10 screen to phone photographs after QR detection and perspective rectification.

The robust operating point has a visible color tint. It should be described as robust data embedding, not invisible steganography. The high PSNR operating point is visually subtle but was not validated for physical capture.

See experiments/full/RESULTS.md, LOGBOOK.md, and paper/main.pdf for the recorded evidence and limitations.

Development

git clone https://github.com/jemsbhai/stegaQR.git
cd stegaQR
pip install -e ".[dev,analysis]"
pytest

Train and evaluate a checkpoint:

python scripts/train.py --mode hybrid --mask-aware --no-calibration `
  --output-dir experiments/run1
python scripts/evaluate.py --checkpoint experiments/run1/best_model.pt
python scripts/evaluate_real.py --checkpoint experiments/run1/best_model.pt

The complete experiment matrix is resumable:

python scripts/run_experiments.py
python scripts/aggregate_results.py
python scripts/generate_figures.py

License

MIT

Release files for stegaQR 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for stegaQR 0.2.0
File Size Uploaded
stegaqr-0.2.0.tar.gz 2.9 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for stegaQR 0.2.0
File Interpreter ABI Platform
stegaqr-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 5.7 MB

Release files / stegaqr-0.2.0.tar.gz

Download URL stegaqr-0.2.0.tar.gz
Size 2.9 MB
Tags Source
SHA-256 checksum
How to use checksums
531eb8a2697d8f9a16b62121e7c781fef9fbd63bbac29d368bd6f4ae27c12209
BLAKE2b-256 checksum
How to use checksums
845dc18842e78b98260d91631809e6781a5e33516ddb4175d9357c6c160ab1df
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / stegaqr-0.2.0-py3-none-any.whl

Download URL stegaqr-0.2.0-py3-none-any.whl
Size 2.8 MB
Tags Python 3
SHA-256 checksum
How to use checksums
a0578dac5aefe71e46b1d6d1be143b1dabba464d8cf923f1fea3984b1e856419
BLAKE2b-256 checksum
How to use checksums
bae9103ccd0543e5154b6afe6062132689d11967a73f2c5b12081541fc0500ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page