QR Code Steganography Extractor
Extract hidden payloads from steganographic QR codes. Auto-detects method across LSB, module color, and PNG metadata. Shows a QR anomaly heuristic and per-method results.
Drop QR code image or click to browse
PNG, JPEG, WebP, BMP — QR code images
Processed in your browser
QR scanning and extraction run in your browser tab; your QR code image is not sent to a server. Usage statistics may record which options were used, never your image. PNG format gives the best accuracy.
How to Extract Hidden Data from a QR Code (5 steps)
- Upload the QR code image (PNG recommended; JPG, screenshots and photos usually destroy pixel-level data)
- The tool scans the QR and shows its primary content
- Keep Auto-Detect, or choose one extraction method in Standard or Forensic mode
- If the payload is encrypted, enter the password on the next step
- Copy your hidden message or download the extracted bytes
QR Extraction Methods — Detection Guide
| Method | Accuracy | Speed | Best For |
|---|---|---|---|
| Auto-Detect | Tries 3 methods in order | Fast | Unknown method. Tries PNG Metadata, LSB Pixel and Module Color in order; stops at the first readable text or recognised file, otherwise lists every result found and selects the best available one |
| PNG Metadata | Exact | Instant | PNG files made with the metadata method |
| LSB Pixel | Exact on an unchanged PNG | Fast | Files made with the LSB method |
| Module Color | Exact on an unchanged PNG | Fast | Files made with the module-colour method |
What the Extractor Looks For
The Extractor reads the three layouts the QR Code Steganography Hider writes. In a PNG it looks for a PNG tEXt chunk with the keyword stego. In the pixels it reads the red low bit of consecutive pixels (LSB), and it separately collects the pixels whose red value is 1, 2, 253 or 254 (Module Color). Each layout starts with a 4-byte length, and a result is only reported when that length fits inside the image, so an ordinary QR image reports nothing.
Module Color extraction does not locate the QR matrix or sample module centres. It scans every pixel of the image in reading order and takes each pixel whose red value is 1 or 2 (dark pixel, bits 1 and 0) or 254 or 253 (light pixel, bits 1 and 0); pure 0 and 255 pixels are skipped. This works because the Hider changes only module-centre pixels and does so in module reading order, so the marked pixels come out in the order they were written. It also means any other pixel with one of those values is taken as a bit: an LSB-made image has pixels at 254, which this method would read as junk (Auto-Detect tries LSB first and stops when it reads text). At least 32 marked pixels are needed for the length, and the length must fit the number found.
If the bytes carry the Hider's Reed-Solomon wrapper or encryption, the Extractor removes the wrapper (repairing changed bytes where it can) and decrypts with your password. It then looks at the result: text, a known file type from its first bytes, other binary data, or data that looks encrypted.
For general images, the LSB Extractor and the Steganography Analyzer read other layouts and run statistical tests.
Reading the Anomaly Score
The score is a quick triage number made from the parts described in the answer to the anomaly-score question above, not a detector. It can be 0 on an image that holds a message (a longer PNG Metadata message adds no pixel change) and it can be high on an image that holds nothing (compression artefacts). Trust the extraction result first and the score second. The score is out of 70, the sum of three parts; the table Anomaly Score Parts lists them.
What Each Layout Looks Like in the File
| Layout | Where the bytes are | How the Extractor reads it | Fails when |
|---|---|---|---|
| PNG Metadata | tEXt chunk, keyword stego, Base64 value | Walks the PNG chunks; Base64-decodes; reads the 4-byte length | The image was re-saved without the chunk or is not a PNG |
| LSB Pixel | Red low bit of pixels from the top-left | Reads 32 bits of length, then that many bytes | Pixel values changed (JPEG, resize, screenshot) |
| Module Color | Red 1/2 on dark, 254/253 on light module centres | Scans every pixel in reading order for those red values (it does not locate the QR matrix); the first 32 marked pixels are the length | Fewer than 32 marked pixels, or pixel values changed |
Anomaly Score Parts
Everything is computed from the uploaded image and nothing is compared with a reference. The score is the sum of three parts and cannot exceed 70; the fourth part of an older 100-point scale was reserved for the method that is not implemented.
| Part | Counts | Points |
|---|---|---|
| PNG metadata | A tEXt chunk with the keyword stego | 20 if present, otherwise 0 |
| Colour anomalies | Pixels whose red value is 1 to 9 on a dark pixel or 246 to 254 on a light pixel | 0 to 25: the count divided by 2, rounded down; 25 from 50 anomalies up |
| LSB-plane entropy | Shannon entropy of the bytes built from the red low bits of all pixels | 0 up to 5.0 bits, 12 above 5.0, 25 above 6.5 |
| Error-correction deviations | Not implemented | Always 0 |
| Total | The three parts added | At most 70. Low: under 25. Medium: 25 to 59. High: 60 or more, which needs the PNG chunk, the full 25 from LSB entropy and a colour part of at least 15 |
Image Formats and Methods
PNG Metadata extraction requires the original PNG file. Pixel-based methods require the original pixel values; support for an image format does not guarantee that its pixels preserve the hidden data. This table says what to expect, from how each format stores pixels; the PNG, BMP, JPEG and lossy WebP cases were checked in a browser (JPEG and WebP at quality 0.95), the lossless WebP case was not.
| Uploaded file | PNG Metadata | LSB Pixel | Module Color |
|---|---|---|---|
| The original PNG from the Hider | Read | Read | Read |
| JPEG | Not available: a converted file has no PNG chunk | Normally lost: lossy compression changes the low bits | Normally lost: the marked values 1, 2, 253, 254 are smoothed |
| WebP | Not available | Lost when saved lossy; a lossless copy was not tested | Lost when saved lossy; a lossless copy was not tested |
| BMP | Not available | Kept by a lossless copy that is not resized or recoloured | Kept by a lossless copy that is not resized or recoloured |
Examples
Input: A plain QR for https://example.com with nothing hidden (165 × 165 px).
Result: All three methods find nothing; the anomaly score is 0 of 70 (Low).
Meaning: The length read from the red low bits is larger than the image can hold, so the LSB method reports nothing.
Input: The same QR with FLAG{qr_demo} hidden by the LSB method (77 pixels changed).
Result: Auto-Detect tries PNG Metadata first (nothing), then LSB, which returns the 13 bytes as text and stops; the anomaly score is 25 (Medium).
Meaning: The 25 comes from the colour part alone: the 77 white pixels at 254 are more than 50 colour anomalies. The LSB-entropy part stays 0 because most of the low-bit plane is still the plain QR. The message itself is plain text.
Input: A message stored with a password and Reed-Solomon RS-20, then 10 of its stored bytes changed in the pixels.
Result: Extraction removes the wrapper, reports 10 bytes repaired, then decrypts with the password.
Meaning: RS-20 repairs up to 10 changed bytes in each 223-byte data block; here all 10 fell in the one block, which is exactly its limit. A block with more changed bytes than the limit cannot be guaranteed to recover, and the result then says the damage is beyond repair (in our tests this was flagged every time). The 16-byte wrapper header is not repaired. Reed-Solomon is outside the encryption, so repair happens before the AES-GCM check.
Input: The same image with a wrong password.
Result: The payload stays encrypted and a message says the password did not decrypt it.
Meaning: A wrong password and altered bytes look the same to the tool.
How the QR Extractor Works
1. Scan
The image is decoded in the browser and jsQR reads the QR's own content and version.
2. Extract
Each method reads its bytes: the tEXt chunk, the red low bits, or every pixel whose red value is 1, 2, 253 or 254 in reading order (Module Color does not locate the QR matrix), each starting with a 4-byte length that must fit the image.
3. Unwrap
A Reed-Solomon wrapper is recognised by its header and removed, repairing what it can; encrypted bytes are decrypted with your password when the AES layout is recognised.
4. Interpret
The bytes are classified as text, a known file type, other binary data or encrypted-looking data, and CTF flag shapes are highlighted.
What the results mean
| Result | What it means | What to do |
|---|---|---|
| Readable text came out | A layout matched and the bytes are text. | Copy it. The method shown tells you which layout the Hider used. |
| A known file type came out | The first bytes match a file signature (PDF, PNG, ZIP and others). | Download the bytes and open them with the matching program. |
| Still encrypted | The bytes have the Hider's AES layout and no password was given, or the password did not work. | Enter the password on the previous step; a wrong password and changed bytes look alike. |
| Nothing found | No layout produced a length that fits the image. | Try each method by hand, use the original PNG, or look for other hiding schemes with the Analyzer. |
| Repair note from Reed-Solomon | The wrapper was found; the note says how many bytes were repaired or that damage was beyond repair. | If damage was beyond repair, compare with the original file. |
Limitations
- Only this tool's three layouts are read. Other steganography tools' QR codes, data after the PNG, and puzzles that hide a second QR code are not covered.
- LSB and Module Color results need the exact pixels of the PNG. JPEG copies, screenshots, resized or photographed images normally lose them (by design; not measured for this tool).
- An image with transparent pixels is read as the browser draws it, which can change the low bits under partly transparent pixels. The Hider's own files are fully opaque, so the safest workflow is to use the original PNG the Hider created.
- The anomaly score is a heuristic out of 70 and has not been checked against other detectors; a short PNG Metadata message scored 20 (Low) in our tests.
- A wrong password and altered encrypted bytes give the same message.
Privacy
The image is decoded and analysed in your browser tab; the tool's own code does not upload it. Usage statistics may record which options were used and coarse facts such as sizes, never your image or the extracted bytes. The host keeps ordinary request logs. For encrypted payloads the password is processed with PBKDF2-HMAC-SHA-256 (100,000 iterations) to derive the AES key; unencrypted payloads do not need a password. The password is turned into a key with PBKDF2-HMAC-SHA-256 (100,000 iterations) and the salt stored in the payload, and the AES-256-GCM authentication tag then checks it. A wrong password and a damaged payload both simply report failure, so the tool cannot tell you which it was, and there is no way to recover a forgotten password. The full description, including what this scheme does not protect, is on the [QR Code Steganography Hider](/steganography/qr-code-steganography-hider) page.
Which Tool Next?
- QR Code Steganography Hider — make a QR code that carries a message
- LSB Extractor — read red, green, blue or alpha low bits of any PNG with a header and bit-depth options
- Steganography Analyzer — bit planes, strings and statistical tests for an image you did not make
- Steganography Detector — estimate whether an image holds an LSB payload, and how much
Frequently Asked Questions
How does Auto-Detect work?
Auto-Detect tries PNG Metadata, then LSB Pixel, then Module Color. It interprets each result (text, known file type, encrypted-looking, other binary) and stops at the first one that reads as text or a known file. If no method gives readable text or a known file, it has tried all three, lists every result found, and selects the best available one in the order text, file, binary, encrypted, noise (a tie keeps the order in which the methods were tried). QR error-correction codeword extraction is not implemented.
Which QR codes can this extract from?
Only data written in this tool's own layouts: a tEXt chunk with the keyword stego, a 4-byte length followed by the red low bits of consecutive pixels, or a 4-byte length followed by red values of 1, 2, 253 and 254 at module centres. A QR made by a different steganography tool, or a puzzle that hides something else in a QR (data after the image, a QR inside a QR), is not read. For those use the Steganography Analyzer or the StegSolve tool.
What is the QR Anomaly Score?
A heuristic from 0 to 70 that counts signs of this tool's methods, not a probability and not a detector. It adds three parts: a PNG-metadata part (20 when a stego chunk exists, otherwise 0), a colour part (0 to 25, from pixels whose red value is just off pure black or white) and an LSB-entropy part (0, 12 or 25, from the entropy of the red low-bit plane). A fourth part, error-correction deviations, is reserved for the method that is not implemented and is always 0. The three parts can add up to 70 at most, which is why the screen shows the score out of 70. Low is under 25, Medium 25 to 59, High 60 or more. In our tests a plain QR scored 0; the same QR with a short message scored 25 for LSB and for Module Color (both from the colour part: 77 and 136 off-white pixels, and the LSB-entropy part stayed 0), and 20 (Low) for PNG Metadata.
Why can the anomaly score be high when no payload is found?
Anything that makes red values drift off pure black and white raises the colour part: JPEG compression, resizing with smoothing, a screenshot of a scaled page. Choose the method by hand and look at the results before concluding anything is hidden.
Can I extract data from a JPEG, WebP or BMP QR code?
PNG Metadata extraction requires the original PNG file: a PNG converted to JPEG, WebP or BMP has no PNG text chunk. Pixel-based methods (LSB and Module Color) require the original pixel values, and support for an image format does not guarantee that its pixels preserve the hidden data. A lossy copy (JPEG, or WebP saved lossy) normally changes them; a lossless copy that is not resized or recoloured (for example a BMP made from the PNG) keeps them. The table Image Formats and Methods sets this out. Use the original PNG.
What happens with a wrong or missing password?
With no password, an encrypted payload is shown as encrypted. With a wrong password, the result says the password did not decrypt it and the bytes stay encrypted; the tool cannot tell a wrong password from changed bytes. With a correct one the AES-GCM tag verifies and the result says so.
What is Reed-Solomon recovery here?
If the Hider wrapped the stored bytes with Reed-Solomon, the Extractor recognises the wrapper by itself, removes it and repairs up to 5, 10 or 15 changed bytes in each 223-byte data block (levels 10, 20, 30); the limit applies per block, not to the whole payload, and a block with more changed bytes than that cannot be guaranteed to recover. The wrapper is a 16-byte header followed by the blocks, each with its parity bytes (10, 20 or 30); the header itself is not repaired. The Extractor reports how many bytes it repaired, or that the damage was beyond what it can repair. It does not help with a heavily re-compressed image.
What do CTF flags look like in results?
Text matching common flag shapes (FLAG{...}, HTB{...}, picoCTF{...}, CTF{...}) is highlighted with a copy button.
Related Tools
QR Code Steganography Hider
Hide secret messages inside fully scannable QR codes. Uses LSB pixel encoding, module color steganography, and PNG metadata embedding. After encoding, the QR is re-scanned with jsQR to check it still reads.
Steganography Detector
Statistical steganalysis with three published tests — chi-square, RS analysis and Sample Pairs — fused into one score and checked against the real StegExpose on a small test set. Payload size estimate. Method fingerprint. WAV audio support. Processed in your browser, not uploaded.