Encodes arbitrary data into one or more QR code PNGs and decodes them back as a form of steganography for data obfuscation.
Simply compile and use QRGenerate.exe command line to encode and decode a given file using the following commands:
.\QRGenerate.exe
Usage:
QRGenerate.exe encode <input_file> <output_dir>
QRGenerate.exe decode <input_dir>
Note that the original filename is embedded in each QR chunk header and restored automatically during decoding.
- The input file is read into memory and split into chunks of up to CHUNK_PAYLOAD_MAX bytes (derived from the Version 40 QR capacity at the configured ECC level).
- Each chunk is wrapped in a binary packet containing a 4-byte magic signature, the total chunk count, the chunk index, the original file size, and the embedded filename.
- Each packet is encoded into a QR code using byte mode, with automatic version selection (1-40) and mask optimization for minimal penalty score.
- The QR code is rendered to an 8bpp grayscale PNG via WIC, with each module scaled to 8x8 pixels and a 4-module quiet zone border.
- The PNGs are written sequentially as
Qr0000.png,Qr0001.png, etc.
- The input directory is scanned for
Qr*.pngfiles. The first file is decoded to extract the total chunk count and original file size from the packet header. - Each PNG is loaded as grayscale, binarised using Otsu's adaptive threshold, and scanned row-by-row for
1:1:3:1:1finder patterns. - Detected finder patterns are validated as capstones, grouped into grid candidates by perspective projection, and refined via iterative perspective jiggling.
- The grid is sampled through the perspective transform, data bits are read in zigzag order, unmasked, de-interleaved into Reed-Solomon blocks, and error-corrected using Berlekamp-Massey with Forney's algorithm.
- The corrected payload is parsed by mode (numeric, alphanumeric, byte, kanji, ECI) and the chunk packet is extracted.
- All chunks are reassembled in order by index into the original file and written to disk. The output filename is recovered from the embedded packet header.
[magic:4][totalChunks:4][chunkIndex:4][origSize:4][nameLen:2][name:nameLen][payload:...]
The QR encode and decode implementations are based on the following projects:
- QR-Code-generator, used for QR code generation and encoding logic.
- quirc, used for QR code detection and decoding from images.