Algorithms
This page documents the checksum and structural validation algorithms implemented by Numerik. All validation is digit-array arithmetic — no regular expressions are used.
Weights: 1, 3, 7, 9, 1, 3, 7, 9, 1, 3
- Strip whitespace. Reject inputs longer than 32 characters. Assert exactly 11 digits; fail with
InvalidLengthotherwise. - Reject non-digit characters; fail with
InvalidCharacters. - Decode the birth date using the century encoding table below. Fail with
InvalidMonthif the stored month does not fall in any known range. Fail withInvalidDateif the decoded date is not a real calendar date. In strict mode, fail withFutureDateif the birth date is in the future. - Compute the checksum: multiply each of the first 10 digits by its corresponding weight and sum the results. Take
sum mod 10, subtract from10, takemod 10again. The result must equal digit 11; fail withInvalidChecksumotherwise. - In strict mode, reject inputs where all 11 digits are identical; fail with
AllSameDigit.
Century encoding
Section titled “Century encoding”The PESEL month digits encode both the birth month and the birth century by adding an offset:
| Stored month range | Real month | Birth century |
|---|---|---|
| 01 – 12 | 01 – 12 | 1900 – 1999 |
| 21 – 32 | 01 – 12 | 2000 – 2099 |
| 41 – 52 | 01 – 12 | 2100 – 2199 |
| 61 – 72 | 01 – 12 | 2200 – 2299 |
| 81 – 92 | 01 – 12 | 1800 – 1899 |
Worked example
Section titled “Worked example”Input: 9 2 0 6 0 5 1 2 1 8 6
| Position | Digit | Weight | Product |
|---|---|---|---|
| 1 | 9 | 1 | 9 |
| 2 | 2 | 3 | 6 |
| 3 | 0 | 7 | 0 |
| 4 | 6 | 9 | 54 |
| 5 | 0 | 1 | 0 |
| 6 | 5 | 3 | 15 |
| 7 | 1 | 7 | 7 |
| 8 | 2 | 9 | 18 |
| 9 | 1 | 1 | 1 |
| 10 | 8 | 3 | 24 |
Sum = 9 + 6 + 0 + 54 + 0 + 15 + 7 + 18 + 1 + 24 = 134
134 mod 10 = 4 → 10 - 4 = 6 → 6 mod 10 = 6 — digit 11 is 6 ✓
Weights: 6, 5, 7, 2, 3, 4, 5, 6, 7
- Strip hyphens and spaces. Reject inputs longer than 32 characters. Assert exactly 10 digits; fail with
InvalidLength. - Reject non-digit characters; fail with
InvalidCharacters. - Assert the first 3 digits are not
000; fail withInvalidFormat. - Multiply each of the first 9 digits by its weight. Sum the products. Take
sum mod 11. The result must equal digit 10. If the modulo gives10, the number is structurally invalid; fail withInvalidChecksum.
Worked example
Section titled “Worked example”Input: 5 2 6 0 2 5 0 2 7 4
| Position | Digit | Weight | Product |
|---|---|---|---|
| 1 | 5 | 6 | 30 |
| 2 | 2 | 5 | 10 |
| 3 | 6 | 7 | 42 |
| 4 | 0 | 2 | 0 |
| 5 | 2 | 3 | 6 |
| 6 | 5 | 4 | 20 |
| 7 | 0 | 5 | 0 |
| 8 | 2 | 6 | 12 |
| 9 | 7 | 7 | 49 |
Sum = 30 + 10 + 42 + 0 + 6 + 20 + 0 + 12 + 49 = 169
169 mod 11 = 4 — digit 10 is 4 ✓
REGON uses a two-stage algorithm. The 14-digit form first validates the base 9 digits before validating the full 14.
9-digit REGON
Section titled “9-digit REGON”Weights: 8, 9, 2, 3, 4, 5, 6, 7
- Strip whitespace. Assert exactly 9 digits.
- Multiply the first 8 digits by the 9-digit weights. Sum. Take
sum mod 11. If the result is10, the checksum digit must be0. Otherwise the result must equal digit 9.
14-digit REGON
Section titled “14-digit REGON”Weights: 2, 4, 8, 5, 0, 9, 7, 3, 6, 1, 2, 4, 8
- Strip whitespace. Assert exactly 14 digits.
- Validate digits 1–9 as a standalone 9-digit REGON (see above).
- Multiply the first 13 digits by the 14-digit weights. Sum. Take
sum mod 11. If the result is10, digit 14 must be0. Otherwise the result must equal digit 14.
KRS has no public checksum algorithm. It is a sequential registry number assigned by the court register. Numerik validates format and range only:
- Strip whitespace. Reject inputs longer than 32 characters. Assert ≤ 10 digits.
- Reject non-digit characters.
- Assert numeric value is greater than
0; fail withAllZeros.
For authoritative verification that a KRS number is actually assigned, query the official KRS registry API.