South African ID number validator
Check whether a 13-digit ID number is well-formed, and see what each part of it means.
This number never leaves your browser. There is no request to this site or anywhere else — the checking happens on this page, nothing is stored, and nothing is logged. Open your browser's devtools on the Network tab and watch it stay empty while you type.
13 digits. Spaces are ignored, so 800101 5009 08 7 is fine.
What the thirteen digits mean
An SA ID number is not random. Reading left to right: digits 1–6 are the date of birth as YYMMDD; digits 7–10 are a sequence number within that day, where 0000–4999 was issued to people registered female and 5000–9999 to people registered male; digit 11 is citizenship, where 0 means South African citizen and 1 means permanent resident; digit 12 is a historical artefact discussed below; and digit 13 is a checksum over the twelve digits in front of it.
The sex digit records what the Department of Home Affairs has on file, which is not necessarily how somebody describes themselves. It can be changed — the Alteration of Sex Description and Sex Status Act 49 of 2003 provides for exactly that, and the number is reissued when it happens. This tool reports what the digits say, not what is true about a person.
Digit 12 was a race classification digit under apartheid and has been unused since 1994. This tool shows that the digit is there and refuses to decode it. There is nothing in that position anyone needs today, and writing the lookup table out would be a strange thing to publish.
What the checksum does and does not prove
The last digit is a Luhn check — the same scheme used on bank cards. It is designed to catch the two mistakes humans actually make when copying numbers: a single mistyped digit, and two adjacent digits swapped. When the checksum fails, you have almost certainly got a typo rather than a forgery.
What it does not do is prove that an ID number belongs to anyone. A checksum is arithmetic, and arithmetic can be satisfied deliberately — you can invent a number that passes every check on this page and belongs to nobody at all. Only the Department of Home Affairs can confirm that a number was issued and to whom, through the National Population Register. If you are verifying somebody's identity for anything that matters, this tool tells you the number is plausible, and that is all it tells you.
The century problem
The date of birth is stored as two digits, so an ID beginning 260315 could mean March 2026 or March 1926 and the number itself contains nothing that distinguishes them. This is the Y2K problem, still sitting quietly in a national identifier.
The usual convention, and the one used here, is that a two-digit year at or below the current one means the 2000s and anything above it means the 1900s — with a check that the resulting date is not in the future, which pushes it back a century if it is. That is a guess, and for anyone born more than about a century ago it is the wrong one. The decoded date of birth below says which century was assumed, rather than presenting the guess as a fact.
Using this in your own code
The same checks are published as @iamlukia/za-id, an npm package for anything that needs to validate ID numbers server-side or in another app — a signup form, an import script, a backend API of your own.
It is not a client for a service — there is no service. The package has no dependencies and makes no network call; it runs inside your own process, the same way this page runs inside your browser.
npm install @iamlukia/za-id