Comparison · detail

Identifiers that pass real validators

The difference between a string of the right length and a number that actually validates.

← Back to Real Fake Data vs Faker

Most official identifiers are self-checking. A national ID, a tax number, an IBAN, a credit-card number all end in a digit computed from the digits before it — a checksum. Type a real one into any validator and it passes; change a single digit and it fails. That self-check is the whole point: it catches transcription errors before they cost anyone money.

So the question for any fake-data tool is not “does it look like an identifier?” but “does it satisfy the checksum?” This is exactly where a general-purpose faker and a validity-first generator part ways.

What Faker actually provides

Faker (@faker-js/faker) ships no national-ID generator at all — there is no PESEL, no NIP, no SSN, no country tax-number or VAT module in the library. Its API is organised into modules like person, location, finance, and internet; none of them cover government or tax identifiers. If you need a PESEL from Faker, you assemble it yourself from string helpers, and nothing computes the check digit for you.

Where Faker does touch checksummed data, it is candid about the limits. Its finance.iban() documentation states plainly that the generated IBAN “might be invalid due to randomly generated bank codes / other country specific validation rules.” It does compute a Luhn check digit for values like credit-card numbers, so not everything is unchecked — but the identifiers most test suites actually need, the national and tax numbers, are simply not in the library. The honest summary: Faker gives you correctly-shaped strings, not a guarantee that the identifier you needed is valid.

What Real Fake Data does instead

Every identifier generator here computes the real check digit from the real algorithm. An IBAN carries correct ISO 7064 mod-97 check digits; each country’s national ID carries its own correct checksum (and, where the format encodes a birth date or sex, those are valid too); each tax number carries its own weighted checksum. The value is synthetic — it belongs to no real person — but it is valid by format, so it flows through the exact validators your production code runs.

That is the property that makes a fixture useful. Your registration form, your import routine, your database constraint — all of them check the identifier, and all of them should accept it, because the whole point of the test is to exercise the path that runs when the input is good.

Why it bites in practice

The failure is quiet and late. Your test seeds a user with a Faker-shaped national ID, submits the form, and the form’s own validation rejects it — so the test never reaches the behaviour it was written to check. Or worse, the invalid value slips past a weak fixture and only fails in a downstream system that validates more strictly, days later, in someone else’s test run.

With checksum-valid data, that entire class of flakiness disappears: the fixture is indistinguishable from real input as far as every validator is concerned.

Numeric identifiers we generate — all checksum-valid

Every one of these is a numeric, self-checking identifier, generated with its correct check digit. Follow any link for that generator’s page.

Try it

Generate any of these in the Playground and check the result against its real validator — no key required. Every national-ID, tax-number and IBAN generator returns checksum-valid values by default.

To be precise about Faker

Faker never claims to generate valid national IDs or tax numbers — it simply has no such generators, and it explicitly documents that its IBANs may be invalid. This is not a bug in Faker; it is a different design goal. The point is only that if you need identifiers that validate, Faker is not the tool that promises them.