Skip to main content

TCKN, VKN and IBAN Validator

Check the checksum of a Turkish national ID, tax number or IBAN in your browser. Nothing is transmitted, and a valid checksum never means the number is real.

Your data never leaves the browserPublished: August 2026
Number type

Enter a number and the result appears here immediately.

What you type stays in your browser and is never sent to a server.

Key Takeaways

  • A checksum proves the digits are internally consistent. It does not prove the number was ever issued, or that it belongs to anyone; only the issuing authority knows that.
  • The tenth digit of a Turkish national ID is computed from a subtraction that can go negative. JavaScript's % is a remainder rather than a modulo, so an uncorrected implementation rejects valid identifiers.
  • An IBAN mod-97 works on a 28 digit number. Computing it with Number() exceeds the safe integer range, which both rejects valid accounts and accepts invalid ones.
  • 11111111110 satisfies the checksum and is not a real number. It is the most widely used test value in Turkey and needs handling of its own.

What a checksum tells you, and what it does not

A check digit is computed from the rest of the number. If it matches, there is no transcription error in the digits. If it does not, something is wrong. That is the entire content of the signal.

What it cannot tell you matters far more: whether the number was ever issued, who holds it, or whether it is still current. Infinitely many numbers satisfy any of these checksums, and almost none of them belong to anyone. This is why the tool reports "checksum passes" rather than "valid person".

Warning

If you collect a national ID in a form, a checksum is the first step and not the last. It catches a typo immediately and saves a pointless round trip to your server. It is not identity verification and must not be presented as such.

The national ID algorithm

Eleven digits, never starting with zero. The last two are derived from the first nine.

text
d10 = ((d1+d3+d5+d7+d9) * 7 - (d2+d4+d6+d8)) mod 10d11 = (d1 + d2 + ... + d10) mod 10

The trap is that the subtraction can produce a negative number. JavaScript's % operator computes a remainder rather than a mathematical modulo, and it keeps the sign of the left operand. The computed digit is then negative and can never equal the real one.

javascript
// Wrong: rejects VALID identifiers such as 19191919190const d10 = (odd * 7 - even) % 10; // Right: brings the result back into 0-9const d10 = (((odd * 7 - even) % 10) + 10) % 10;

This is invisible in review because most identifiers are unaffected: only the ones whose intermediate sum goes negative break. A user enters a genuine ID, the system rejects it, and nobody can reproduce the problem.

Fakes that pass the checksum

When the first ten digits are identical, the rules force a particular eleventh digit, so the number satisfies both checks. 11111111110 is the best known of these and appears in nearly every tutorial and test fixture in the country.

The tool reports these as their own category. Saying "checksum failed" would be untrue, because it did not fail; saying "valid" would be considerably worse. The honest answer names it as a well-known test value.

The tax number uses a different algorithm entirely

Ten digits, and unrelated to the national ID rule. Each digit gains a position weight, the result is taken modulo ten, then folded through a power of two and reduced modulo nine.

The step everyone drops is that a modulo-nine result of zero counts as nine. Without that branch a validator rejects a substantial share of genuine tax numbers.

Note

A tax number may begin with zero while a national ID may not. Storing one as a number therefore destroys it. Keep both as strings, always.

IBAN, and the overflow that breaks it

IBAN validation is ISO 13616: move the first four characters to the end, map letters to numbers (A=10 through Z=35), and the resulting value modulo 97 must equal 1.

A Turkish IBAN becomes a 28 digit number under that transformation. Number.MAX_SAFE_INTEGER is 16 digits, so computing the remainder with Number() produces nonsense.

javascript
// For a VALID TR IBAN the true remainder is 1Number(digits) % 97   // -> 96, because of overflowBigInt(digits) % 97n  // -> 1n, correct // No BigInt needed, and safe in every runtime:let r = 0;for (const ch of digits) r = (r * 10 + Number(ch)) % 97;

A length check is required as well. Mod-97 alone accepts an IBAN with a digit added or removed roughly one time in ninety seven. Turkey is exactly 26 characters, and checking that turns those odds into a certain rejection.

Why there is no generator

All of these checksums are trivially invertible. Choose nine digits freely, derive the last two, and you have a well-formed identifier in constant time with no search involved. Writing a generator is technically nothing.

That is exactly why there is not one. The algorithms are published by the issuing authorities, so a validator gives a bad actor nothing they lack. A button that emits a hundred well-formed numbers, or a bulk mode that screens a pasted list for the plausible ones, is a different thing entirely: those are the fraud-relevant primitives, and both are absent by design.

Nothing leaves your browser

What you type is never transmitted, stored or logged. The computation runs entirely locally, and once the page has loaded you can disconnect and it keeps working. Given that the input is personal data by definition, that is a requirement rather than a feature.

Frequently Asked Questions

The checksum passes, so is the number real?
No. A checksum only shows the digits are consistent with each other. Whether the number was issued, who holds it and whether it is current are questions only the issuing authority can answer. Infinitely many numbers pass, and almost none belong to anyone.
Why is 11111111110 reported as not valid?
Because it satisfies the checksum but is not a real number. It is the most widely used test value in Turkey. The tool reports it as its own case: calling it valid would mislead, and calling it a checksum failure would simply be wrong.
Is what I type stored anywhere?
No. The calculation runs in your browser and nothing is sent over the network. Load the page, disconnect, and you will find the tool still works.
Why can I not generate a valid number?
These checksums are invertible, so building a generator is easy, but easy does not make it right. Validating one number is a legitimate need; producing them in bulk, or screening a pasted list for the plausible ones, serves fraud. Neither exists here.
Can I use this algorithm in my own form?
Yes, and you should: it catches a user typo instantly. Do not substitute it for identity verification. Watch the two traps described above, the negative remainder and the use of Number() for the IBAN modulo.

Tool and article by , Senior Software Engineer. Published: August 2026.