MRZ parser and check digit calculator
Paste the machine-readable zone of a passport, identity card or visa – TD3, TD2 or TD1. The format is detected, every field is read out, and every ICAO 9303 check digit is recomputed and compared with the one printed. It all runs in your browser; nothing leaves the page.
What a machine-readable zone is
A machine-readable zone is the block of fixed-width lines at the foot of a passport or identity card, standardised by ICAO Doc 9303. It encodes the document number, issuing state, name, nationality, date of birth, sex and expiry date, each at a fixed offset, with check digits that verify the reading.
Where each field sits in TD1, TD2 and TD3
Positions are counted from 1 on each line, the way ICAO 9303 numbers them. Every check digit sits right after the field it protects; the composite digit is the last character of its line.
| Field | TD3 (passport) | TD2 | TD1 (ID card) |
|---|---|---|---|
| Document code | line 1, 1–2 | line 1, 1–2 | line 1, 1–2 |
| Issuing state | line 1, 3–5 | line 1, 3–5 | line 1, 3–5 |
| Name | line 1, 6–44 | line 1, 6–36 | line 3, 1–30 |
| Document number | line 2, 1–9 | line 2, 1–9 | line 1, 6–14 |
| its check digit | line 2, 10 | line 2, 10 | line 1, 15 |
| Nationality | line 2, 11–13 | line 2, 11–13 | line 2, 16–18 |
| Date of birth | line 2, 14–19 | line 2, 14–19 | line 2, 1–6 |
| its check digit | line 2, 20 | line 2, 20 | line 2, 7 |
| Sex | line 2, 21 | line 2, 21 | line 2, 8 |
| Expiry date | line 2, 22–27 | line 2, 22–27 | line 2, 9–14 |
| its check digit | line 2, 28 | line 2, 28 | line 2, 15 |
| Personal number | line 2, 29–42 | – | – |
| its check digit | line 2, 43 | – | – |
| Composite check digit | line 2, 44 | line 2, 36 | line 2, 30 |
How a check digit is calculated
- Take the field the digit protects – the document number, the date of birth, the date of expiry, the personal number, or the whole composite range.
- Give every character its value: a digit counts as itself, a letter as its position in the alphabet plus nine (A = 10, Z = 35), and the filler < as zero.
- Multiply each value by its position weight. The weights repeat 7, 3, 1 across the field, starting at 7 on the first character.
- Add the products together.
- The check digit is that sum modulo 10 – the last digit of the total.
Worked through on the specimen's passport number AM7304518 – an invented document belonging to nobody:
| Character | Value | Weight | Product |
|---|---|---|---|
| A | 10 | 7 | 70 |
| M | 22 | 3 | 66 |
| 7 | 7 | 1 | 7 |
| 3 | 3 | 7 | 21 |
| 0 | 0 | 3 | 0 |
| 4 | 4 | 1 | 4 |
| 5 | 5 | 7 | 35 |
| 1 | 1 | 3 | 3 |
| 8 | 8 | 1 | 8 |
| Sum, then modulo 10 | 214 → 4 | ||
So the digit printed after AM7304518 in that
zone is 4.
Load the TD3 example above and the parser recomputes the same number in front of you.
The composite digit
One more digit covers most of the zone at once: the composite. It is computed the same way, over a range that skips the fields no digit protects – and in TD1 that range spans two lines, which is where a hand-written parser usually goes wrong. A zone whose field digits all pass and whose composite fails has been transcribed correctly in pieces and assembled wrongly.
What the digits do not cover
No check digit covers the name, and none covers the issuing state. A misread in either is silent: the arithmetic still balances. That is why reading the printed side of the document as well, and comparing the two readings, catches what the digits cannot.
Questions people ask
What is an MRZ?
A machine-readable zone is the block of fixed-width lines at the foot of a passport or identity card, standardised by ICAO Doc 9303. It encodes the document number, issuing state, name, nationality, date of birth, sex and expiry date, each at a fixed offset, with check digits that verify the reading.
Which formats does this tool support?
All three ICAO 9303 layouts: TD3, the two lines of 44 a passport carries; TD2, two lines of 36; and TD1, the three lines of 30 on an identity card or residence permit. It also reads the two visa layouts, MRV-A and MRV-B, which have no composite digit. The format is detected from the number of lines and their length, and every check digit the format has is recomputed.
Why does a check digit fail?
Almost always because one character in the field it protects was misread or mistyped: an O for a 0, a B for an 8, a filler lost at the end of a line. The table shows the digit the zone prints beside the one the data gives, and the field the digit covers. When a field digit passes and the composite fails, look at the characters between the fields – the composite also covers the field digits themselves.
Can it read the zone from a photo?
No. This page reads text you paste, and nothing leaves your browser. Reading the zone and the printed page off a photo is what the recognition API does: one HTTP call with the image, and the fields come back as JSON with the same check digits already verified.
Do you store any of my data?
No. The zone you paste is parsed by code running in your own browser: nothing is uploaded, and no request carrying it is made. This page is a static file, and the only request it makes after it loads is to ask whether there is a service notice to show at the top – a call that carries nothing you typed. The recognition API is a separate thing you have to call deliberately.
Where to go next
- MRZ generator – build a valid zone with correct check digits for a test fixture.
- TD1, TD2 and TD3 – the three layouts, their line and character counts, and where the standard defines each.
- Passport OCR API – the printed side as well as the encoded one, read from a photo in one request.
- Free passport OCR API – the first calls with no account, as a single curl command.
- Passport OCR by country – the issuing states this API reads, each with a specimen zone of its own.