Thailand’s national identification number (เลขประจำตัวประชาชน) is a 13-digit code issued by the Department of Provincial Administration (DOPA, กรมการปกครอง) to every person registered in the country. It appears on the plastic national ID card (บัตรประจำตัวประชาชน) and serves as the primary identifier for government services, banking, healthcare, tax filing, and SIM-card registration throughout Thailand. The printed form uses the pattern P-RRRR-SSSSS-CC-C, where hyphens are cosmetic separators — the actual number is always the 13 digits alone.
This validator implements the full official Royal Thai Government check-digit specification and decodes every structural segment of the number so you can confirm validity and understand what each part encodes — all without sending anything to a server.
How it works
The 13-digit number is split into five segments:
| Positions | Segment | Meaning |
|---|---|---|
| 1 | Person-type code (P) | Registration category 1–8 (see FAQ) |
| 2–3 | Province code (RR) | Two-digit province of the issuing DOPA office |
| 4–5 | District code (RR) | Two-digit district (อำเภอ) within that province |
| 6–10 | Registration serial (SSSSS) | Sequential number within that district office |
| 11–12 | Personal serial (CC) | Distinguishes people registered the same day |
| 13 | Check digit (C) | Mathematical verification digit |
The check-digit algorithm
The official algorithm is a weighted sum mod 11, then mod 10:
- Multiply each of the first 12 digits by its descending weight (13 down to 2).
- Sum all 12 products.
- Compute
remainder = sum mod 11. - Compute
check = (11 − remainder) mod 10.
The final mod 10 step handles two edge cases that would otherwise produce an out-of-range value: when remainder = 0 the subtraction gives 11, which mod 10 yields 1; when remainder = 1 the subtraction gives 10, which mod 10 yields 0. Every other remainder (2–10) maps naturally to a single digit without wrapping.
Worked example
Take the obviously-fake number 1-1001-00001-00-6 (do not use as real data):
The 13 digits are: 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 6
| Step | Detail |
|---|---|
| Digit × weight | 1×13 + 1×12 + 0×11 + 0×10 + 1×9 + 0×8 + 0×7 + 0×6 + 0×5 + 1×4 + 0×3 + 0×2 |
| Products | 13 + 12 + 0 + 0 + 9 + 0 + 0 + 0 + 0 + 4 + 0 + 0 |
| Sum | 38 |
| 38 mod 11 | 5 |
| (11 − 5) mod 10 | 6 ✓ |
| Digit 13 in example | 6 |
| Result | Match — check digit is correct, number is structurally valid |
Person-type digit is 1 (Thai citizen registered at birth), province code is 10 (Bangkok), district code 01 (district 1 of that province), registration serial 00001, personal serial 00.
Formula note
The use of mod 10 at the final step is an important detail that distinguishes this scheme from simpler mod-11 checksums. Most mod-11 algorithms treat a remainder of 0 or 10 as special cases requiring a sentinel character (X or similar) because the result would be out of the 0–9 digit range. Thailand’s specification avoids this entirely by applying a second modulus: (11 − remainder) mod 10 always produces a single digit 0–9, so no sentinel is ever needed and every possible 12-digit prefix maps to a valid numeric check digit. This means the algorithm accepts every prefix — there is no “inherently invalid” combination as there is in Luhn or Lund schemes.
Every calculation happens client-side — your ID number is never transmitted anywhere.