Skip to main content

Validator, generator and parser for Bulgarian unique citizenship numbers (EGN/ЕГН).

Project description

egn

PyPI package Build Status Documentation Status Coverage

A Python library and command-line tool for validating, parsing and generating the Bulgarian Unified Civil Number (ЕГН / EGN — Единен граждански номер).

Библиотека и команден ред на Python за проверка, анализ и генериране на български Единни граждански номера (ЕГН).


Table of contents / Съдържание


What is an EGN? / Какво е ЕГН?

English. The EGN (Unified Civil Number) is a 10-digit identifier assigned to every Bulgarian citizen and to every foreign resident. It encodes:

Positions Meaning
1–2 Year of birth (last two digits)
3–4 Month of birth, with a century offset: +20 for births in the 1800s, +40 for births after 2000
5–6 Day of birth
7–9 Regional code (0 – 999), assigned by the civil registry and reflecting the place of registration
9 The last digit of the regional code also encodes the sex: even = male, odd = female
10 Check digit (mod-11 / mod-10 weighted checksum)

Български. ЕГН-то е 10-цифрен идентификатор, съдържащ датата на раждане, район на регистрация, пол и контролна цифра. Месецът е кодиран с добавени +20 за рождени през XIX век и +40 за рождени след 2000 г. Полът се определя от последната цифра на кода на областта: четна → мъж, нечетна → жена.

Note / Забележка. Dates between 1 April 1916 and 13 April 1916 do not exist — Bulgaria adopted the Gregorian calendar by skipping those 13 days. EGNs carrying such dates are considered invalid by this library.


Installation / Инсталация

pip install egn

Supported Python: 3.6+ (the library uses f-strings).


Python API

import egn

validate(egn)

Return True if egn is a valid EGN, False otherwise. Accepts either a str or an int (ints are zero-padded to 10 digits).

Връща True, ако ЕГН-то е валидно.

>>> egn.validate('0021010899')
True
>>> egn.validate(21010899)        # int, will be zero-padded
True
>>> egn.validate('1234567890')
False

parse(egn)

Return a dict describing the EGN. Raises Exception('Invalid EGN') if the input is invalid.

Връща речник с данните, извлечени от ЕГН-то.

>>> egn.parse('1111136273')
{
    'year': 1911,
    'month': 11,
    'day': 13,
    'datetime': datetime.datetime(1911, 11, 13, 0, 0),
    'region_bg': 'София',
    'region_en': 'Sofia',
    'region_iso': 'BG-22',
    'gender': 'Female',
    'egn': '1111136273',
}

get_date(egn)

Return just the date portion of an EGN (decoded year, month, day and a datetime). Returns False for malformed input.

>>> egn.get_date('9941011142')
{'year': 2099, 'month': 1, 'day': 1, 'datetime': datetime.datetime(2099, 1, 1, 0, 0)}

generate(date_from, date_to, gender, region, limit)

Deterministically enumerate valid EGNs matching the given constraints. All parameters are optional and can be mixed freely.

Генерира всички валидни ЕГН-та, които отговарят на зададените филтри. Всички параметри са по избор и могат да се комбинират.

Parameter Type Default Meaning
date_from str (YYYY-MM-DD) '1800-01-01' Earliest date of birth to enumerate.
date_to str (YYYY-MM-DD) today Latest date of birth to enumerate.
gender 'm' / 'male' / 'f'/ 'female' None Filter by sex. None returns both.
region str None Region name in Latin, Cyrillic or ISO 3166-2 (e.g. 'Sofia', 'София', 'BG-22'). None returns every region.
limit int / None 10 Maximum number of EGNs to return. Pass None to enumerate every combination.

Examples:

# All EGNs for men born in Sofia on 2020-10-15.
egn.generate(region='Sofia', gender='m',
             date_from='2020-10-15', date_to='2020-10-15',
             limit=None)
# -> 49 EGNs (one per even region code in 624-721)

# All female EGNs in Burgas across January 2020.
egn.generate(region='Burgas', gender='f',
             date_from='2020-01-01', date_to='2020-01-31',
             limit=None)

# Every EGN for a single day regardless of region or gender.
egn.generate(date_from='1999-12-31', date_to='1999-12-31', limit=None)
# -> 1000 EGNs (one per region code 000-999)

# Using Cyrillic or ISO region names.
egn.generate(region='Пловдив', limit=5)
egn.generate(region='BG-16',   limit=5)

How partial inputs compose:

date_from/date_to gender region limit Result
date range any any N First N EGNs in the range, all regions, both sexes
single day 'm' any None Every male EGN born that day, across all regions
date range any 'Varna' None Every EGN born in Varna during the range
date range 'f' 'BG-22' None Every female EGN born in Sofia in the range

generate_random(gender, region, limit)

Return limit random valid EGNs. Each EGN has a uniformly random date between 1800-01-01 and yesterday and a uniformly random region (or the one you specified).

Генерира произволни ЕГН-та.

>>> egn.generate_random(limit=3, region='Varna', gender='f')
['8841020217', '2643026019', '5424077115']

Command-line interface / Команден ред

After installation the egn command is available:

# Validate
$ egn -v 0021010899
0021010899 is valid!

# Parse (prints JSON)
$ egn -p 9941011142
{"year": 2099, "month": 1, "day": 1, "region_bg": "Варна", ...}

# Generate with full filter set
$ egn -g --from 2020-10-15 --to 2020-10-15 --region Sofia --gender m
# -> prints 49 EGNs, one per line

# Generate — omit --limit to enumerate every combination
$ egn -g --from 2020-01-01 --to 2020-01-01 --region Pernik
# -> prints all 18 EGNs for that day and region

# Generate with a cap
$ egn -g --from 2020-01-01 --to 2020-12-31 --region Burgas --limit 100

# Random EGNs
$ egn -r --limit 5
$ egn -r --region Пловдив --gender f --limit 3

Flags:

Flag Purpose
-v EGN Validate a single EGN.
-p EGN Parse a single EGN and print JSON.
-g Generate EGNs matching the given filters.
-r Generate random EGNs.
-l N / --limit N Cap the number of results. Omit with -g to enumerate every combination.
--gender m/f Filter by sex.
--region NAME Latin, Cyrillic, or ISO 3166-2 region name.
--from DATE ISO date YYYY-MM-DD. Default 1800-01-01.
--to DATE ISO date YYYY-MM-DD. Default: today.

Regions / Области

The regional code in positions 7–9 of the EGN maps to one of 29 administrative regions. The library ships with the full table, keyed by ISO 3166-2 code, Bulgarian name, and English transliteration.

Библиотеката съдържа пълната таблица на 29-те области, като търсенето работи с латиница, кирилица или ISO 3166-2 код.

ISO English Български Code range
BG-01 Blagoevgrad Благоевград 000–043
BG-02 Burgas Бургас 044–093
BG-03 Varna Варна 094–139
BG-04 Veliko Turnovo Велико Търново 140–169
BG-05 Vidin Видин 170–183
BG-06 Vratza Враца 184–217
BG-07 Gabrovo Габрово 218–233
BG-08 Dobrich Добрич 790–821
BG-09 Kurdzhali Кърджали 234–281
BG-10 Kyustendil Кюстендил 282–301
BG-11 Lovech Ловеч 302–319
BG-12 Montana Монтана 320–341
BG-13 Pazardzhik Пазарджик 342–377
BG-14 Pernik Перник 378–395
BG-15 Pleven Плевен 396–435
BG-16 Plovdiv Пловдив 436–501
BG-17 Razgrad Разград 502–527
BG-18 Ruse Русе 528–555
BG-19 Silistra Силистра 556–575
BG-20 Sliven Сливен 576–601
BG-21 Smolyan Смолян 602–623
BG-22 Sofia София 624–721
BG-23 Sofia (county) София (окръг) 722–751
BG-24 Stara Zagora Стара Загора 752–789
BG-25 Targovishte Търговище 822–843
BG-26 Haskovo Хасково 844–871
BG-27 Shumen Шумен 872–903
BG-28 Yambol Ямбол 904–925
BG-XX Other Друг 926–999

Algorithm / Алгоритъм

The checksum in position 10 is computed from the first 9 digits using the weights (2, 4, 8, 5, 10, 9, 7, 3, 6):

checksum = (sum(weight_i * digit_i for i in 1..9) mod 11) mod 10

If that value equals the 10th digit, the EGN is well-formed. The library additionally verifies that positions 1–6 decode to a real calendar date, that the date is not inside the 1–13 April 1916 Gregorian gap, and that the regional code is in range.

Reference: http://www.grao.bg/esgraon.html#section2


Development / Разработка

git clone https://github.com/miglen/egn.git
cd egn
python3 -m venv .venv && source .venv/bin/activate
pip install -e . pytest
pytest test/

Contributions welcome. Please include a test case with any bug fix or new feature.

Приноси са добре дошли. Моля, добавяйте тест за всяка корекция или нова възможност.


License / Лиценз

GNU General Public License v3.0 — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

egn-0.1.5.tar.gz (34.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

egn-0.1.5-py2.py3-none-any.whl (31.3 kB view details)

Uploaded Python 2Python 3

File details

Details for the file egn-0.1.5.tar.gz.

File metadata

  • Download URL: egn-0.1.5.tar.gz
  • Upload date:
  • Size: 34.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for egn-0.1.5.tar.gz
Algorithm Hash digest
SHA256 b4f53c840d73390b36c6de5da883aa4abb2873b871a7a4518ab83834f0fd5580
MD5 87f4bed329c0d22705195e837feccf4a
BLAKE2b-256 341840e3459475d926c88b9c69c5f69ca72176eeda627ff14323a655314207e4

See more details on using hashes here.

File details

Details for the file egn-0.1.5-py2.py3-none-any.whl.

File metadata

  • Download URL: egn-0.1.5-py2.py3-none-any.whl
  • Upload date:
  • Size: 31.3 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for egn-0.1.5-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 173faa518d9222661e6e5155140d91398885f97120678471404b855ecf5278e8
MD5 ecb54e645a6bda604a468f2c4aaf7ebf
BLAKE2b-256 fc20e757705afa9297cc82f836c2d55182b1a3bf27a52c3615fba757dd2afa9f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page