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.

Austrian data: Austrian IBAN , Austrian SVNR

Belgian data: Belgian IBAN , Belgian Rijksregisternummer

Bulgarian data: Bulgarian EGN , Bulgarian IBAN

Canadian data: Canadian bank account , Canadian SIN , Canadian transit (branch routing) number

Croatian data: Croatian IBAN , Croatian JMBG , Croatian OIB

Cypriot data: Cypriot IBAN , Cyprus TIC

Czech data: Czech IBAN , Czech rodné číslo

Danish data: Danish CPR , Danish IBAN

Dutch data: Dutch BSN , Dutch IBAN

Estonian data: Estonian IBAN , Estonian isikukood

Finnish data: Finnish henkilötunnus , Finnish IBAN , Finnish Y-tunnus

French data: French IBAN , French NIR

German data: German IBAN , German Steuer-IdNr

Greek data: Greek AFM , Greek AMKA , Greek IBAN

Hungarian data: Hungarian adóazonosító jel , Hungarian IBAN , Hungarian személyi azonosító , Hungarian TAJ

Irish data: Irish IBAN , Irish PPSN

Italian data: Italian Codice Fiscale , Italian IBAN

Latvian data: Latvian IBAN , Latvian personas kods

Lithuanian data: Lithuanian asmens kodas , Lithuanian IBAN

Luxembourg data: Luxembourg IBAN , Luxembourg matricule

Maltese data: Maltese IBAN

Polish data: Polish IBAN , Polish PESEL

Portuguese data: Portuguese IBAN , Portuguese NIF

Romanian data: Romanian CNP , Romanian IBAN

Slovak data: Slovak IBAN , Slovak rodné číslo

Slovenian data: Slovenian davčna številka , Slovenian EMŠO , Slovenian IBAN

Spanish data: Spanish DNI , Spanish IBAN , Spanish NIE

Swedish data: Swedish IBAN , Swedish personnummer

US data: US ABA routing transit number , US bank account , US Social Security Number

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.