> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sparklane.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Why doesn't my scan match the number printed under the barcode?

> Leading zeros, check digits, add-ons and scanner prefixes: why scanned data differs from the digits printed under a barcode, and how to fix it.

export const type_0 = "ean-13"

The digits printed under a barcode are a version of its data laid out for people to read. They aren't a copy of what the bars encode, so a scan can be longer, shorter or punctuated differently and still be correct.

Both are right. The fix is almost never to change the label. It's to decide which form your app stores, and convert every scan to it.

## Find your case

| What you see | Likely cause |
| - | - |
| The scan has one more digit, a `0` at the front | [An extra leading zero](#an-extra-leading-zero) |
| 8 digits printed, 12 scanned (or 6) | [UPC-E expands from 8 digits to 12](#upc-e-expands-from-8-digits-to-12) |
| The last digit is missing | [A missing last digit](#a-missing-last-digit) |
| The first or last digit is missing | [Digits printed outside the bars](#digits-printed-outside-the-bars) |
| Hyphens on the label, none in the scan | [ISBNs and hyphens](#isbns-and-hyphens) |
| 2 or 5 extra digits on the end | [An add-on that came along](#an-add-on-that-came-along) |
| Parentheses on the label, none in the scan | [Parentheses missing from the scan](#parentheses-missing-from-the-scan) |
| Fields run together, or odd characters appear | [Invisible characters](#invisible-characters) |
| Extra characters at the start, like `]E0` | [A prefix or suffix your scanner added](#a-prefix-or-suffix-your-scanner-added) |
| Asterisks on the label, none in the scan | [Asterisks around the text](#asterisks-around-the-text) |
| The case and the item have different numbers | [A different number on the case](#a-different-number-on-the-case) |

## An extra leading zero

| Printed | Scanned |
| - | - |
| `0 61414 10000 7` | `0061414100007` |

The label is a [UPC-A](/reference/barcode-types/upc-a), which has 12 digits. Its bars are identical to an [EAN-13](/reference/barcode-types/ean-13) that starts with 0, so many scanners and most phone cameras report it as 13 digits.

The same product can turn up with 14 digits too. Systems that store GTINs (Global Trade Item Numbers) often pad them to 14: `00061414100007`.

All three are the same number. Compare them after padding to one length, never as raw text.

## UPC-E expands from 8 digits to 12

| Printed | Scanned |
| - | - |
| `0 123456 5` | `012345000065` |

[UPC-E](/reference/barcode-types/upc-e) is a UPC-A with its zeros squeezed out so it fits on a small pack. The printed digits are the short form. Many scanners expand it back to the full UPC-A, and some go further and add the EAN-13 leading zero.

Some scanners do the opposite and send only the six middle digits, `123456`, dropping the first and last.

Expand UPC-E to a full GTIN before you store or compare it.

## A missing last digit

| Printed | Scanned |
| - | - |
| `0 61414 10000 7` | `06141410000` |

The last digit of a UPC or EAN is its [check digit](/reference/check-digits). Scanners use it to confirm the read, and most have a setting that controls whether they pass it on. With that setting off, you get every digit except the last.

Turn check digit transmission on. A GTIN without its check digit isn't a GTIN, and you can't validate it.

The reverse happens with [Code 39](/reference/barcode-types/code-39): its optional check character is in the bars but often isn't printed, so the scan has one character more than the label.

## Digits printed outside the bars

On a UPC-A the first and last digits sit outside the bars, often in smaller type. On an EAN-13 the first digit does. People typing the number by hand, and some label templates, leave them off.

They're part of the number. `61414 10000` on its own isn't enough to identify the product.

## ISBNs and hyphens

| Printed | Scanned |
| - | - |
| `ISBN 978-0-306-40615-7` | `9780306406157` |

Books print the [ISBN](/reference/barcode-types/isbn) with hyphens above the barcode. The hyphens separate the parts of the ISBN for people. The barcode is a plain EAN-13 and has none.

Older books show a 10-digit ISBN, `0-306-40615-2`, above a barcode that still scans as 13 digits. The 13-digit form adds 978 to the front and has a different check digit. Some scanners can convert a 978 barcode back to the 10-digit form, which gives you a third variation.

Store ISBNs as 13 digits with no hyphens.

## An add-on that came along

| Printed | Scanned |
| - | - |
| `9780306406157` and, to the right, `51995` | `978030640615751995` |

Books and magazines often carry a second, smaller barcode to the right of the main one. A 5-digit add-on usually holds a price, and a 2-digit add-on holds an issue number. If your scanner is set to read add-ons, it joins the two into one string.

Decide whether you need the add-on. If you don't, turn add-on reading off or take the first 13 digits. If you do, split the string at 13.

## Parentheses missing from the scan

| Printed | Scanned |
| - | - |
| `(01)09521234567899(17)271231(10)ABC123` | `01095212345678991727123110ABC123` |

[GS1-128](/reference/barcode-types/gs1-128) and GS1 DataMatrix labels pack several fields into one barcode. Each field starts with a short code called an Application Identifier: `01` for the GTIN, `17` for the expiry date, `10` for the batch.

The label prints each identifier in parentheses so people can find the fields. The parentheses aren't encoded. In the scan, the identifiers and their values run together.

Don't split the string by position or by looking for the identifiers as text, because the same digits can appear inside a value. Parse it properly: see [GS1 Application Identifiers](/sdk/gs1/application-identifiers).

## Invisible characters

| Printed | Scanned |
| - | - |
| `(01)09521234567899(10)ABC123(17)271231` | `010952123456789910ABC123␝17271231` |

Some GS1 fields, like the batch, vary in length. When one is followed by another field, the barcode marks where it ends with a separator, shown here as `␝`. It's a control character (GS, ASCII 29) with nothing to print, so it can show up as a blank, a box, or not at all.

Scanners that act as keyboards are the usual source of trouble. Keyboards have no key for this character, so the scanner may drop it. Then `ABC123` and `17271231` run together, and nothing in the string says where the batch stops.

If you read GS1 barcodes through a keyboard-style scanner, set the scanner to send a visible stand-in for the separator. If you use ZipZapKit, its [GS1 parsing](/sdk/gs1/application-identifiers) handles the separators for you.

Other invisible characters to expect:

* **Enter or Tab on the end.** Most scanners add one after every scan so the cursor moves on.
* **Line breaks inside the data.** Driver's license barcodes contain them by design. See [AAMVA test barcodes](/hardware/aamva-test-barcodes).

## A prefix or suffix your scanner added

| Printed | Scanned |
| - | - |
| `9521234567899` | `]E09521234567899` |

Scanners can put a short code in front of every scan to say what type of barcode it was. The standard codes start with `]`:

| Prefix | Barcode type |
| - | - |
| `]E0` | EAN-13, UPC-A, UPC-E |
| `]E4` | EAN-8 |
| `]C1` | GS1-128 |
| `]e0` | GS1 DataBar |
| `]d2` | GS1 DataMatrix |
| `]Q3` | GS1 QR Code |

Scanners can also be set up with any custom prefix or suffix, which is how a store's scanners end up sending something like `A9521234567899`.

The prefix is useful if you need to know the barcode type, and it's the only way to get it from a keyboard-style scanner. If you don't need it, turn it off in the [scanner's configuration](/hardware/configuration). Otherwise strip it before you use the value.

## Asterisks around the text

| Printed | Scanned |
| - | - |
| `*ABC123*` | `ABC123` |

[Code 39](/reference/barcode-types/code-39) uses an asterisk as its start and stop character. Some labels print the asterisks, especially ones made with a barcode font. Scanners don't send them.

## A different number on the case

| On the item | On the case |
| - | - |
| `9521234567899` | `19521234567896` |

The barcode on a shipping case is usually an [ITF-14](/reference/barcode-types/itf-14). It identifies the case, not the item inside, so it's a different number by design.

Often it's the item's number with one digit added to the front to show the packaging level. That changes the check digit, so the last digit differs too. You can't rely on this pattern, though. A brand may give a case a completely unrelated number.

Look up the relationship between case and item in your product data. Don't derive one from the other.

## What to do about it

1. **Pick one form to store.** For product numbers, store GTINs as 14 digits, padded with zeros on the left. That fits UPC-A, EAN-13, EAN-8 and ITF-14 in one field.
2. **Normalize every scan into that form** before you save or compare it. This is the step that makes a UPC-A scan match an EAN-13 scan of the same product.
3. **Validate the check digit, not the length.** Length varies for legitimate reasons. A wrong check digit never does.
4. **Never compare a scan to text copied from the label.**

In ZipZapKit, steps 2 and 3 are modifiers on the field:

```swift theme={null}
ScanField("Product barcode", text: $gtin)
    .barcodeTypes(.retailProduct)
    .normalize(.gtin14)
    .validate(.checkDigit)
```

See [Normalization](/sdk/modifiers/normalization) and [Validation](/sdk/modifiers/validation).

To see exactly what's in a specific barcode, decode it:

<CardGroup cols={2}>
  <Card title="Decode one" icon="magnifying-glass" href={`/tools/barcode-anatomy?type=${type_0}`}>
    Scan or paste a barcode and see every part of it.
  </Card>

  <Card title="Make one" icon="wand-magic-sparkles" href={`/tools/generator?type=${type_0}`}>
    Generate a valid barcode from fields.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.