Skip to content

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

  1. Strip whitespace. Reject inputs longer than 32 characters. Assert exactly 11 digits; fail with InvalidLength otherwise.
  2. Reject non-digit characters; fail with InvalidCharacters.
  3. Decode the birth date using the century encoding table below. Fail with InvalidMonth if the stored month does not fall in any known range. Fail with InvalidDate if the decoded date is not a real calendar date. In strict mode, fail with FutureDate if the birth date is in the future.
  4. Compute the checksum: multiply each of the first 10 digits by its corresponding weight and sum the results. Take sum mod 10, subtract from 10, take mod 10 again. The result must equal digit 11; fail with InvalidChecksum otherwise.
  5. In strict mode, reject inputs where all 11 digits are identical; fail with AllSameDigit.

The PESEL month digits encode both the birth month and the birth century by adding an offset:

Stored month rangeReal monthBirth century
01 – 1201 – 121900 – 1999
21 – 3201 – 122000 – 2099
41 – 5201 – 122100 – 2199
61 – 7201 – 122200 – 2299
81 – 9201 – 121800 – 1899

Input: 9 2 0 6 0 5 1 2 1 8 6

PositionDigitWeightProduct
1919
2236
3070
46954
5010
65315
7177
82918
9111
108324

Sum = 9 + 6 + 0 + 54 + 0 + 15 + 7 + 18 + 1 + 24 = 134

134 mod 10 = 410 - 4 = 66 mod 10 = 6 — digit 11 is 6


Weights: 6, 5, 7, 2, 3, 4, 5, 6, 7

  1. Strip hyphens and spaces. Reject inputs longer than 32 characters. Assert exactly 10 digits; fail with InvalidLength.
  2. Reject non-digit characters; fail with InvalidCharacters.
  3. Assert the first 3 digits are not 000; fail with InvalidFormat.
  4. 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 gives 10, the number is structurally invalid; fail with InvalidChecksum.

Input: 5 2 6 0 2 5 0 2 7 4

PositionDigitWeightProduct
15630
22510
36742
4020
5236
65420
7050
82612
97749

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.

Weights: 8, 9, 2, 3, 4, 5, 6, 7

  1. Strip whitespace. Assert exactly 9 digits.
  2. Multiply the first 8 digits by the 9-digit weights. Sum. Take sum mod 11. If the result is 10, the checksum digit must be 0. Otherwise the result must equal digit 9.

Weights: 2, 4, 8, 5, 0, 9, 7, 3, 6, 1, 2, 4, 8

  1. Strip whitespace. Assert exactly 14 digits.
  2. Validate digits 1–9 as a standalone 9-digit REGON (see above).
  3. Multiply the first 13 digits by the 14-digit weights. Sum. Take sum mod 11. If the result is 10, digit 14 must be 0. 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:

  1. Strip whitespace. Reject inputs longer than 32 characters. Assert ≤ 10 digits.
  2. Reject non-digit characters.
  3. Assert numeric value is greater than 0; fail with AllZeros.

For authoritative verification that a KRS number is actually assigned, query the official KRS registry API.

If this saved you time → ☕ Buy me a coffee