Generator · Romanian data

Romanian CNP

Endpoint GET /v1/ro/cnp

What it covers

Returns a valid Romanian CNP (Cod Numeric Personal) with a correct check digit. Constrain with `sex` and age/birth-date filters (the CNP encodes the full birth date). Contradictory combinations are rejected with a 400. Set `invalid=true` for a deliberately wrong check digit.

How it’s calculated

The 13th digit of a Romanian CNP is a weighted-sum modulo-11 check over the first 12 digits, with the special rule that a remainder of 10 becomes 1.

Algorithm

  1. Take the first 12 digits of the CNP in order: S YYMMDD JJ NNN — S (century+sex marker), YYMMDD (birth date), JJ (county code), NNN (serial).
  2. Use the fixed weight vector [2, 7, 9, 1, 4, 6, 3, 5, 8, 2, 7, 9], aligned position-by-position with those 12 digits.
  3. Multiply each digit by its weight at the same position, and add all 12 products together to get a weighted sum.
  4. Compute the remainder of that sum modulo 11.
  5. If the remainder is exactly 10, the check digit is 1; otherwise the check digit is the remainder itself (0-9).
  6. Append this single check digit as the 13th and final digit of the CNP.

Worked example

CNP for a male born 2001-02-03, county 12, serial 345: 501020312345?

First 12 digits: 5 0 1 0 2 0 3 1 2 3 4 5
Weights:        2 7 9 1 4 6 3 5 8 2 7 9
Products: 5x2=10, 0x7=0, 1x9=9, 0x1=0, 2x4=8, 0x6=0, 3x3=9, 1x5=5, 2x8=16, 3x2=6, 4x7=28, 5x9=45
Weighted sum = 10+0+9+0+8+0+9+5+16+6+28+45 = 136
136 mod 11 = 136 - (11 x 12=132) = 4
Remainder is 4 (not 10), so the check digit is 4

The check digit is 4, giving the full CNP 5010203123454.

Edge cases

  • Remainder 10 is the only special case: it maps to check digit 1 rather than producing a two-digit result.
  • The leading digit S is not the check digit — it encodes both century and sex (1/2=1900s, 3/4=1800s, 5/6=2000s; odd=male, even=female) and still participates in the weighted sum via weight 2.
  • Foreigner markers 7/8 (residents) and 9 do not encode a century and are not emitted by this generator, but the check-digit rule itself is identical for them.

Gotchas

  • The weight vector is a fixed 12-element constant (2,7,9,1,4,6,3,5,8,2,7,9); it does not repeat a shorter cycle and must be applied left-to-right starting at the very first digit S.
  • Digits are handled as a string throughout (leading zeros in YYMMDD and JJ are significant); toDigits converts the 12-character string to numbers only at the arithmetic boundary — never route a CNP through Number.
  • The check is a plain remainder, not an 11-complement: e.g. remainder 4 gives check digit 4, not 7.

Parameters

ParameterTypeDescription
atAgeintegerExact age in years at request time.
bornAfterstringpattern ^\d{4}(?:-\d{2}(?:-\d{2})?)?$Born after this date or fragment (YYYY, YYYY-MM, YYYY-MM-DD).
bornBeforestringpattern ^\d{4}(?:-\d{2}(?:-\d{2})?)?$Born before this date or fragment (YYYY, YYYY-MM, YYYY-MM-DD).
bornOnstringpattern ^\d{4}(?:-\d{2}(?:-\d{2})?)?$Born on a date or within a fragment: YYYY, YYYY-MM, or YYYY-MM-DD.
countinteger1–1000Number of records to return, 1–1000 (your plan may lower this). Omitted returns a single record; set it for a batch.
edgebooleanRestrict output to edge-case values.
extremebooleanReturn a correct value wrapped in a hostile encoding (untrimmed whitespace, invisible/zero-width characters, BOM, or bidi/combining marks). Homoglyphs are excluded so the value stays machine-parseable; it still validates after normalisation.
invalidbooleanReturn a CNP with a deliberately wrong check digit; date/sex/county stay valid.
olderThanintegerMinimum age in years at request time.
seedintegerInteger seed for reproducible output: the same seed always yields the same record.
sex"m" | "f"Encoded sex: "m" or "f".
youngerThanintegerMaximum age in years at request time.

Response fields

FieldTypeDescription
valuestringThe CNP in the requested format.
digitsstringThe canonical 13-digit CNP.
birthDatestringThe encoded birth date, ISO `YYYY-MM-DD`.
sex"m" | "f"Encoded sex: `m` (odd leading digit) or `f` (even).
countystringThe 2-digit county code (`JJ`) encoded in the CNP.

Other generators for Romania

See all generators for Romania →

The same kind of identifier elsewhere

Try it

Generate a live example below — every response is valid by format and entirely synthetic.