Barcode Verifier & Scanner
Choose a barcode image or point your camera at a printed symbol. A decoding engine that is independent from this site's generator reads the bars and shows exactly what a scanner sees. Images and camera frames stay on your device: nothing is uploaded or retained.
Decode a barcode
PNG, JPEG, WebP, or SVG, up to 10 MB. For the best result, include the complete symbol and blank quiet zones on both sides.
- Detected format
- —
- Decoded value
—
Privacy: file objects, pixels, camera frames, and decoded values remain in this browser tab. The scanner performs no upload and analytics events never contain the decoded value.
What this verification proves
A successful decode proves that this image contains a supported one-dimensional barcode and tells you the characters encoded in its bar pattern. It is a useful independent check after downloading from the barcode generator: compare the decoded result here with the payload the generator reported. The generator uses JsBarcode to draw symbols; this verifier uses ZXing to read their pixels, so the two sides do not merely repeat the same answer.
Go deeper: the guide How the verifier decodes what you see follows one number from typed digits to decoded pixels — validation, the payload cross-check, the independent decode, what is withheld and where the check stops — with every figure computed at build time. The guides hub covers the other engines behind this site.
The independent-reader idea
Every barcode this site produces passes through two pieces of software with two distinct jobs. Rendering — turning an accepted payload into the module pattern of a symbol — is the work of JsBarcode, an MIT-licensed open-source library, pinned to an exact version and used unmodified. Everything around it is this site's own, implemented independently from published algorithm descriptions: the validator that runs before the renderer and decides what the symbol will carry, and the reader that runs after it. The reader's job is to refuse to take the renderer's output on trust. On a generator page it rasterises the actual SVG you are looking at, asks ZXing — a decoding engine independent from the renderer — to read those pixels, and compares what came back with the payload the validator approved. The PNG export is rendered to its own canvas and decoded again before the file is released; the single-barcode PDF exporter translates the independently decoded SVG's rectangles and caption into native PDF vector geometry rather than embedding a screenshot.
This page is that reader with the automation removed. Instead of the generator's rendered SVG, it reads the image you choose or the frame your camera shows; and instead of comparing the result with a validated payload — there is none here — it shows you the decoded value and the detected format and leaves the comparison to you. It is offered for the 7 symbologies this site generates — Code 128, EAN-13, EAN-8, UPC-A, ISBN, Code 39 and ITF-14 — with ISBN barcodes decoding as EAN-13 because that is what their bars carry. It is an end-to-end check of pixels, not another calculation over a source string: the only input is the picture.
One comparison, 2 failure reasons
On a generator page the reader's result goes through a single comparison, and the check can fail in exactly 2 ways, each named in the engine:
-
decode-failed— the reader could not produce a decode from the rendered bars (the SVG, or the PNG canvas before export); the message says the barcode was withheld and suggests a shorter value or reporting the example. -
payload-mismatch— the decoder read a text that is not the validated payload; the message quotes what it read.
The message says to report the example but does not say where; this site's channel for that is the contact page. Whichever reason is named, the preview and the download controls stay withheld. A mismatch is reported, never repaired.
The comparison itself is exact, with 2 disclosed equivalences, and both come from one fact recorded in the engine: a UPC-A and the EAN-13 that begins with 0 followed by its twelve digits are the same printed symbol. A reader may therefore report a UPC-A as its zero-prefixed thirteen-digit spelling, or a zero-led EAN-13 as the twelve digits with the zero stripped, and the engine accepts both. It accepts nothing else. The table hands the engine's own comparison, at build time, 8 readings — 1 cited vector read exactly, 2 equivalences, 2 cited numbers reported as something other than their payload, and 3 fictional misreadings. 3 are accepted and 5 withheld.
| Symbology | Validated payload | Reading | What the reading is | Engine's verdict |
|---|---|---|---|---|
| EAN-13 |
5901234123457
|
5901234123457
|
The cited vector, read exactly | Accepted — same symbol |
| EAN-13 |
5901234123457
|
5901239123457
|
Fictional misreading: position 7 read as 9 | Withheld — payload mismatch |
| EAN-13 |
5901234123457
|
5901234123167
|
Fictional look-alike that passes its own check digit | Withheld — payload mismatch |
| UPC-A |
036000291452
|
0036000291452
|
The cited UPC-A spelled as thirteen digits — the same printed symbol | Accepted — same symbol |
| EAN-13 |
0036000291452
|
036000291452
|
The cited UPC-A, read as a zero-led EAN-13, reported without its zero | Accepted — same symbol |
| EAN-13 |
5901234123457
|
901234123457
|
First digit dropped from a number that does not start with 0 | Withheld — payload mismatch |
| ISBN |
9780306406157
|
0306406152
|
The ISBN-10, normalised, not the ISBN-13 the bars carry | Withheld — payload mismatch |
| Code 128 |
BG-2026-0001
|
bg-2026-0001
|
Fictional reading differing only in letter case | Withheld — payload mismatch |
Every verdict above is the engine's output for that pair, computed when this page was built; if the comparison rule changed, the table would change with it or the build would fail.
Two rows are the common surprises. An ISBN barcode carries the ISBN-13,
not the ISBN-10 you typed: the cited 0-306-40615-2 is verified and converted before rendering,
and the note beneath the generator says so — "ISBN-10 0306406152 verified (check character 2), then converted to ISBN-13 9780306406157: 978 prefix + your 9 data digits + recomputed EAN-13 check digit 7." — so the bars decode as 9780306406157, and a reading of 0306406152 would be a mismatch. And Code 128 carries letter case — lowercase letters are what force its code set B — with no visible check
digit to fall back on, so the fictional
BG-2026-0001 read as bg-2026-0001 is simply a different payload.
Decoded values are compared with the payload the notes report, never with your keystrokes.
Why compare, rather than re-check the digit
It would be simpler to re-run the check-digit arithmetic on whatever the decoder read and
accept anything that verifies. The engine does not, and the cited vector shows why. Enter
5901234123457 complete on the EAN-13 generator and the validator
runs in its verified mode — "You entered all 13 digits — the check digit 7 was verified against the first 12 and is correct." Now suppose the decoder read
position 7 as 9 instead of
4, giving 5901239123457. That misreading fails
its own check digit — the data digits require 2, the final digit read
is 7 — so arithmetic alone would catch it.
But move two neighbouring digits in opposite directions and the arithmetic goes quiet. Change
position 11 from 4 to
1 (it carries weight 1, so the weighted sum
falls by 3) and position 12 from
5 to 6 (weight
3, so the sum rises by 3). The result, 5901234123167,
verifies — expected 7, supplied 7 — and is not
the number you entered. A check digit proves a number is consistent with itself; only a comparison
with the payload you validated proves it is the number you meant. That is the engine's rule on a
generator page, and it is the comparison this page asks you to make by hand. For the arithmetic
itself, see
how GTIN check digits are computed.
Reading what this page shows you
The status line tells you which state the reader is in. Before you act it waits — the decoder
is not loaded until you ask for a scan. Afterwards it reports either a result or a refusal. A
result fills two fields: Detected format, the symbology family the decoder
recognised, and Decoded value, the characters the bars carry, with a button
to copy them. A refusal after a scan attempt means no supported linear barcode was found in
the picture — the counterpart of what a generator page reports as decode-failed
when the reader could not produce a decode from the rendered bars (the SVG, or the PNG canvas before
export), except that here nothing is withheld, because there is nothing to withhold: the picture
is yours. The fixes are the ones listed under
supported barcode families below. Some refusals come before any scan and
are separate from it: an image over the size limit stated beside the file field, a file whose type
is not an image at all, and a camera route that is closed — either because the page is not served
over HTTPS in a browser with camera access, or because camera access was unavailable or denied.
The camera refusals leave the image route open.
Read the result against the payload, not against your memory of what you typed. For a GTIN
entered without its check digit, the payload is one digit longer than your input: the cited
11 UPC-A data digits 03600029145 become 036000291452, the check digit
2 having been computed and appended. For an ISBN-10, the payload is the ISBN-13.
For Code 39, lowercase letters have been uppercased, and the note said so. If the value you see
differs from the payload by any character, the file is not the file you meant to ship, whatever
its check digit says.
The format field deserves one caution of its own. A UPC-A may be reported in its thirteen-digit EAN-13 spelling and a zero-led EAN-13 in its twelve-digit UPC-A spelling, because the two are one symbol. The engine's comparison accepts exactly those 2 equivalences, as the table above shows, and treats every other difference as a mismatch.
What it does not prove
Decoding an on-screen image does not certify a future print run. Ink spread, low contrast, glossy packaging, resizing, missing quiet zones, and printer scaling can make a good source file fail after printing. Always scan a physical production sample at its final size. For retail numbers, a successful decode also does not prove the GTIN is licensed — see when GS1 registration is needed.
The deliberate exception: bulk label sheets
One product on this site is not read back, and the methodology says so in as many words: bulk PDF label sheets are the deliberate exception. Each row receives structural and check-digit validation before rendering — the same normalise, enforce, compute-or-verify, report sequence as a single barcode — but the assembled PDF rows are not individually decoded. A sheet is therefore validated, not independently read, and this page does not change that: it accepts PNG, JPEG, WebP and SVG images, not PDFs. The honest route for a sheet is the one every page here recommends — print a sample at its final size and scan it with the device used in your workflow. The bulk label generator states the same exception where the sheets are made.
The limit beyond that is the same for every product. No browser check can certify ink, substrate, scaling, contrast, or quiet zones after printing, so a physical production sample must still be scanned. Where this site quotes physical figures at all they come from GS1 member organisation size guides, linked where used, and otherwise the guidance stays qualitative. This page verifies digits and character sets as read from pixels; it says nothing about whether a printed symbol will scan.
Supported barcode families
The verifier targets the linear formats generated on this site: EAN-13, EAN-8, UPC-A, Code 128, Code 39, and Interleaved 2 of 5 / ITF-14. ISBN barcodes decode as EAN-13 because the bars carry the 13-digit Bookland EAN. It is intentionally not presented as a universal QR or document scanner. If an image fails, crop away surrounding graphics while retaining the blank margins, use a sharper source, and make sure the bars are not rotated or distorted.
A practical two-step production check
- Generate and download the barcode, then open that file here. Confirm that the independently decoded value exactly matches the validated payload the generator's note reported.
- Place the barcode in the final artwork, print a real sample at 100% scale, and scan that physical sample with the device used in your workflow.
Common misreadings
- "Decoded" means registered. It means the bars carry that value. Whether a GTIN is licensed or an ISBN registered is not something pixels can tell; see Do I need a GS1 barcode?
- A decoded screen image will scan when printed. That is optics, not math — scan a physical production sample.
-
If the check digit verifies, the value is right.
5901234123167verifies and is not5901234123457. Compare the whole payload. - The decoded value should match what I typed. It should match the validated payload the notes reported: check digit appended, ISBN converted, Code 39 uppercased.
- A label sheet is verified like a single barcode. Its rows are validated; the assembled PDF is not decoded.
Verifier FAQ
Is this the same reader the generator uses?
Yes. The methodology describes this page as exposing the same independent-reader idea for an uploaded image or camera view. On a generator page the reader runs for you — against the rendered SVG, and again against the PNG canvas before export — and its result is compared with the validated payload automatically. On this page there is no validated payload to compare against, so the decoded value is shown and the comparison is yours to make.
What should I compare the decoded value with?
With the payload the generator's notes reported, not with your keystrokes. The bars carry the validated payload. Enter the cited ISBN-10 0-306-40615-2 on the ISBN generator and the note reads "ISBN-10 0306406152 verified (check character 2), then converted to ISBN-13 9780306406157: 978 prefix + your 9 data digits + recomputed EAN-13 check digit 7." — so this page should show 9780306406157. Enter the cited 11 UPC-A data digits 03600029145 and the check digit 2 is computed and appended, so the value to expect is 036000291452. Lowercase Code 39 input is uppercased before rendering, and the note says so.
The decoded value differs from my number — how serious is that?
Any difference is a mismatch; a generator page would withhold the barcode for it. Some differences are also caught by the arithmetic: read one digit of the cited 5901234123457 differently, as the fictional misreading 5901239123457, and the check digit no longer verifies — the data digits require 2, the final digit read is 7. But the fictional look-alike 5901234123167 passes its own check digit and is still not that number. That is why the engine compares the whole payload and never the check digit alone, and why you should too.
Why does the verifier show thirteen digits for my UPC-A, or twelve for my EAN-13?
Because the two spellings are the same printed symbol, and a reader may report either. The engine's comparison accepts exactly 2 equivalences for that reason: 036000291452 reported as 0036000291452, and 0036000291452 reported as 036000291452. Everything else must match exactly — for 5901234123457, a reading of 901234123457 is a mismatch.
Does a successful decode mean the barcode will scan after printing?
No. This page decodes the pixels of an image or a camera frame. No browser check can certify ink, substrate, scaling, contrast, or quiet zones after printing, so a physical production sample must still be scanned, with the device used in your workflow. The methodology calls that boundary math, not optics.
Are bulk PDF label sheets decoded like single barcodes?
No — the methodology states this as a deliberate exception. Each row of a bulk sheet receives structural and check-digit validation before rendering, but the rows of the assembled PDF are not individually decoded. Treat a sheet as validated, not read back: print a sample at its final size and scan it.
For the arithmetic behind GTIN check digits, use the check digit calculator. For implementation boundaries, test vectors, and licensing, read the methodology and accuracy notes.