Generator · Bulgarian data

Bulgarian EGN

Endpoint GET /v1/bg/egn

What it covers

Returns a valid Bulgarian EGN (Единен граждански номер, the unified civil number) with a correct check digit. Constrain with `sex` and age/birth-date filters (the full birth date is encoded). Contradictory combinations are rejected with a 400. Set `invalid=true` for a deliberately wrong check digit.

How it’s calculated

The Bulgarian EGN's 10th digit is a weighted mod-11 check digit over the first nine digits, with the awkward residue 10 folded to 0 via a mod-10 overflow rule.

Algorithm

  1. Take the first nine EGN digits d1..d9 (the six-digit YYMMDD birth-date head, where the month carries the century via +20 for the 1800s / +0 for the 1900s / +40 for the 2000s, followed by a three-digit serial).
  2. Apply the positional weight vector W = [2, 4, 8, 5, 10, 9, 7, 3, 6] to those nine digits: multiply each digit di by its weight Wi.
  3. Sum all nine products to get S = sum(di * Wi).
  4. Compute the raw remainder: raw = S mod 11.
  5. Apply the mod-10 overflow rule: check digit = raw mod 10. In practice raw is 0..10, so this only matters when raw == 10, which maps to 0; every other raw value (0..9) is returned unchanged.
  6. Append this single check digit as the 10th and final digit of the EGN.

Worked example

EGN 750523 405 ? (born 1975-05-23, serial 405)

First nine digits: 7,5,0,5,2,3,4,0,5 (YY=75 -> 1975, MM=05, DD=23, serial=405).
Weights: 2,4,8,5,10,9,7,3,6.
Products: 7*2=14, 5*4=20, 0*8=0, 5*5=25, 2*10=20, 3*9=27, 4*7=28, 0*3=0, 5*6=30.
Sum S = 14+20+0+25+20+27+28+0+30 = 164.
raw = 164 mod 11 = 164 - 154 = 10.
check = raw mod 10 = 10 mod 10 = 0.

The check digit is 0, so the full EGN is 7505234050.

Edge cases

  • Residue 10: when the weighted sum mod 11 equals 10, the mod-10 overflow rule folds it to check digit 0 (source passes overflow 'mod10', so mod11CheckDigit never returns undefined here — the code even guards this as 'unreachable').
  • Century is folded into the month field: 1800s births encode month+20, 1900s encode the month as-is, 2000s encode month+40; the check-digit math runs over those already-encoded digits, not the calendar month.

Gotchas

  • Sex is encoded in the 9th digit's parity with the OPPOSITE convention to many schemes: even 9th digit -> male, odd -> female (see sexParity / the 'sex: ninth % 2 === 0 ? m : f' line). It does not affect the checksum computation, only which payloads occur.
  • The weight vector is EGN-specific and non-monotonic: [2, 4, 8, 5, 10, 9, 7, 3, 6] — note the 10 in position 5 and that it is NOT a simple 1..9 ramp.

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 an EGN with a deliberately wrong check digit; date/sex 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 EGN in the requested form (currently the bare 10 digits).
digitsstringThe canonical 10-digit EGN.
birthDatestringThe encoded birth date, ISO `YYYY-MM-DD`.
sex"m" | "f"Encoded sex: `m` (even 9th digit) or `f` (odd 9th digit).

Other generators for Bulgaria

See all generators for Bulgaria →

The same kind of identifier elsewhere

Try it

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