Skip to main content
Polish ID Numbers · 8 min read

PESEL Generator

Generate valid 11-digit PESEL numbers with correct checksums. Pick birth date and gender or go fully random. Bulk generate 1, 5, 10, or 100 at a time. Every number passes 1-3-7-9 weighted validation.

By Matt Rybin
Published Updated
Date

Not a developer? If you’re looking to understand what PESEL is, how to get one, or how to decode an existing number, see our PESEL Checker & Decoder, a full guide to the Polish national identification number.

PESEL Format Specification

PESEL is Poland’s 11-digit national identification number 1. For a full guide on what PESEL is, how to get one, and how it’s used in Poland, see our PESEL Checker.

The format is YYMMDDSSSGK:

Position Field Description
1–2 YY Last two digits of birth year
3–4 MM Month of birth (with century offset, see below)
5–6 DD Day of birth
7–9 SSS Serial number (sequential within same birth date)
10 G Gender digit: odd (1,3,5,7,9) = male, even (0,2,4,6,8) = female
11 K Check digit (weighted mod-10 checksum)

No two people share a PESEL. Numbers are never reused after death 1. The serial + gender digits allow up to 5,000 assignments per gender per day.

Century Encoding

The month field doubles as a century marker. An offset is added to the calendar month to encode which century the person was born in:

Century Offset Month range Example: March
1800–1899 +80 81–92 83
1900–1999 +0 01–12 03
2000–2099 +20 21–32 23
2100–2199 +40 41–52 43
2200–2299 +60 61–72 63

To decode: determine which range the month code falls in, subtract the offset, and you have the calendar month and century.

To encode (what this generator does): take the calendar month, add the offset for the target century, and write the result into positions 3–4.

In practice, you’ll only encounter the 1900s (01–12) and 2000s (21–32) ranges. This generator handles all five.

Checksum Algorithm

The 11th digit is a weighted modular checksum. The weights are fixed: 1, 3, 7, 9, 1, 3, 7, 9, 1, 3.

Steps:

  1. Multiply each of the first 10 digits by its weight.
  2. Sum the products.
  3. Take the sum modulo 10.
  4. Subtract from 10.
  5. Take the result modulo 10. This is the check digit.

Worked example: 90080517352

Digits: 9 0 0 8 0 5 1 7 3 5
Weights: 1 3 7 9 1 3 7 9 1 3
Products: 9 0 0 72 0 15 7 63 3 15
Sum: 184
184 mod 10 = 4
10 - 4 = 6
6 mod 10 = 6

But the 11th digit is 2, not 6, so this example PESEL is invalid. If the check digit doesn’t match, the number was mistyped or fabricated. Every number this generator produces has a correct check digit.

JavaScript

function peselCheckDigit(digits) {
const weights = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3];
const sum = digits
.slice(0, 10)
.reduce((acc, d, i) => acc + d * weights[i], 0);
return (10 - (sum % 10)) % 10;
}
function isValidPesel(pesel) {
if (!/^\d{11}$/.test(pesel)) return false;
const digits = [...pesel].map(Number);
return digits[10] === peselCheckDigit(digits);
}

Python

def pesel_check_digit(digits: list[int]) -> int:
weights = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3]
total = sum(d * w for d, w in zip(digits[:10], weights))
return (10 - total % 10) % 10
def is_valid_pesel(pesel: str) -> bool:
if not pesel.isdigit() or len(pesel) != 11:
return False
digits = [int(d) for d in pesel]
return digits[10] == pesel_check_digit(digits)

PHP

function isValidPesel(string $pesel): bool {
if (!preg_match('/^\d{11}$/', $pesel)) return false;
$weights = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3];
$digits = array_map('intval', str_split($pesel));
$sum = 0;
for ($i = 0; $i < 10; $i++) {
$sum += $digits[$i] * $weights[$i];
}
$check = (10 - ($sum % 10)) % 10;
return $digits[10] === $check;
}

Regex Patterns

Basic format check (11 digits, nothing else):

^\d{11}$

This matches any 11-digit string. It does NOT validate the checksum, date logic, or month encoding. Use it as a first-pass filter before running the checksum algorithm above.

Stricter structural pattern (valid date ranges, valid month codes):

^[0-9]{2}(0[1-9]|1[0-2]|2[1-9]|3[0-2]|4[1-9]|5[0-2]|6[1-9]|7[0-2]|8[1-9]|9[0-2])(0[1-9]|[12]\d|3[01])\d{5}$

This validates that positions 3–4 contain a legal month code (from any century range) and positions 5–6 contain a plausible day (01–31). It still doesn’t validate the checksum or catch impossible dates like February 30. For full validation, combine the regex with the checksum function above.

Why regex alone isn’t enough: A PESEL like 99023112345 passes both patterns: the month (02) is valid and the day (31) is within range. But February 31 doesn’t exist. And neither pattern checks whether digit 11 is the correct checksum. Always validate programmatically.

Edge Cases for Testing

If you’re building PESEL validation or processing, these are the cases that break naive implementations. Use the generator above to produce numbers matching each scenario, or use the examples below.

Post-2000 births. Month codes 21–32 trip up parsers that assume months are always 01–12. A PESEL starting with 052706 is July 6, 2005, not June with an invalid month. Make sure your date parser subtracts the century offset before interpreting the month.

Leap year dates. February 29 is valid in leap years but invalid in others. PESEL 000229xxxxx is valid (2000 was a leap year) but 010229xxxxx is not (2001 was not). Your validator should check actual calendar validity, not just range.

Century boundaries. 000121xxxxx means January 21, 1900 (month code 01, 1900s range). 002121xxxxx means January 21, 2000 (month code 21, 2000s range). Same year digits, different centuries. Test both.

Gender digit zero. Digit 10 = 0 means female (0 is even). Some implementations incorrectly treat 0 as “unset” or skip it. Zero is a valid even digit.

Check digit zero. When the modular calculation produces 10, the check digit is 0 (not 10). (10 - 0) % 10 = 0. Test this boundary.

Day boundaries. Day 01 and day 31 (where valid) are edge cases. Months with 28, 29, or 30 days should reject day 31. April, June, September, November have 30 days maximum.

PESEL vs. NIP vs. REGON

Poland uses three main identification numbers. If you’re building a system that handles Polish data, you may need to validate or generate all three.

Number Digits Assigned to Contains personal data Generator
PESEL 11 Individuals Yes (birth date, gender) This page
NIP 10 Businesses, sole proprietors, VAT payers No NIP Generator
REGON 9 or 14 Businesses, organizations No REGON Generator

All three use weighted checksum algorithms, but with different weight sequences. A valid PESEL is not a valid NIP and vice versa.

Frequently Asked Questions

Are these real PESEL numbers?

No. The numbers are structurally valid (correct checksums, valid date encoding, and proper gender digits), but they are not assigned to real people. They are generated randomly and are safe to use in test environments.

Can I use generated PESELs in production systems?

No. Use generated numbers only in development, testing, staging, and demo environments. Using a generated PESEL in a production system risks colliding with a real person's number. Polish law treats PESEL as personal data under RODO (GDPR). If you need test data for a production-adjacent environment, use numbers from the 1800s or 2200s century ranges. These are extremely unlikely to match living people.

How does the generator ensure valid checksums?

The generator constructs the first 10 digits based on your date and gender inputs (or random values), then calculates the 11th digit using the standard 1-3-7-9 weighted algorithm. The check digit is always computed, never random.

What's the maximum number of valid PESELs for a given date?

Each birth date supports 5,000 male and 5,000 female PESELs (serial digits 000–999 combined with 10 possible gender digits per serial, divided by gender). For a single date and gender combination, there are exactly 5,000 possible valid numbers.

Does the generator handle all century ranges?

Yes. You can generate PESELs for birth dates from 1800 through 2299. The tool automatically applies the correct month encoding for each century range.

How do I validate a PESEL I received?

Use our PESEL Checker. It decodes the birth date, gender, and validates the checksum. The checker also has a full guide on what PESEL is and how it's used in Poland.

References

  1. Population Registry Act (Consolidated Text 2024) - isap.sejm.gov.pl 2

Matt Rybin

Hey!

I'm Matt Rybin

I work hard on building the best statistical portal in Poland. If you know any way I could improve Poland.gg to be even better, please reach out!

MATT RYBIN MATTRYBIN

NIP: 6793260169 · REGON: 524468418

ul. Kalwaryjska 69/9, 30-504 Kraków, Poland

Poland.gg newsletter

Making sense of Poland

I dig through Polish legal databases and government statistics so you don't have to. Property deep-dives, tax guides, free tools, and the kind of data stories that never make it into English.

// Max one email a week

Featured as showcase #1322 on dane.gov.pl, Poland's official open data portal.

© 2026 Poland.gg