• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

thorgate / django-esteid / 4354524044

pending completion
4354524044

push

github-actions

GitHub
Merge pull request #67 from thorgate/updates

404 of 571 branches covered (70.75%)

Branch coverage included in aggregate %.

12 of 12 new or added lines in 6 files covered. (100.0%)

1594 of 2012 relevant lines covered (79.22%)

0.79 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.03
/esteid/validators.py
1
import re
1✔
2

3
from esteid.constants import Countries
1✔
4
from esteid.exceptions import InvalidIdCode, InvalidParameter
1✔
5

6

7
ID_CODE_EE_REGEXP = re.compile(r"^[1-6] \d{2} [01]\d [0123]\d \d{4}$", re.VERBOSE)
1✔
8
ID_CODE_LT_REGEXP = ID_CODE_EE_REGEXP
1✔
9
ID_CODE_LV_REGEXP = re.compile(r"^\d{6}-\d{5}$")
1✔
10

11

12
def id_code_ee_is_valid(id_code: str) -> bool:
1✔
13
    """
14
    Validates Estonian ID code, including checksum.
15

16
    https://et.wikipedia.org/wiki/Isikukood
17
    """
18
    if isinstance(id_code, str) and bool(re.match(ID_CODE_EE_REGEXP, id_code)):
1✔
19
        step1_factors = "1234567891"
1✔
20
        checksum = sum(int(i) * int(d) for i, d in zip(step1_factors, id_code[:10])) % 11
1✔
21
        if checksum == 10:
1!
22
            step2_factors = "3456789123"
×
23
            checksum = sum(int(i) * int(d) for i, d in zip(step2_factors, id_code[:10])) % 11
×
24
            if checksum == 10:
×
25
                checksum = 0
×
26
        if int(id_code[-1]) == checksum:
1✔
27
            return True
1✔
28
    return False
1✔
29

30

31
def id_code_lv_is_valid(id_code: str) -> bool:
1✔
32
    """
33
    Validates Latvian ID code
34

35
    Given the input in the following format ABCDEF-XGHIZ,
36
    Z must equal to (1101-(1*A+6*B+3*C+7*D+9*E+10*F+5*X+8*G+4*H+2*I)) | Mod 11 | Mod 10.
37
    """
38
    if isinstance(id_code, str) and bool(re.match(ID_CODE_LV_REGEXP, id_code)):
1✔
39
        id_code = id_code.replace("-", "")
1✔
40
        factors = [1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
1✔
41
        checksum = (1101 - sum(i * int(d) for i, d in zip(factors, id_code[:10]))) % 11 % 10
1✔
42
        if int(id_code[-1]) == checksum:
1✔
43
            return True
1✔
44
    return False
1✔
45

46

47
# Lithuanian ID code format is the same as Estonian.
48
id_code_lt_is_valid = id_code_ee_is_valid
1✔
49

50

51
ID_CODE_VALIDATORS = {
1✔
52
    Countries.ESTONIA: id_code_ee_is_valid,
53
    Countries.LATVIA: id_code_lv_is_valid,
54
    Countries.LITHUANIA: id_code_lt_is_valid,
55
}
56

57

58
def validate_id_code(id_code, country):
1✔
59
    try:
1✔
60
        validator = ID_CODE_VALIDATORS[country]
1✔
61
    except (KeyError, TypeError) as e:
×
62
        raise InvalidParameter(f"Unsupported country '{country}'", param="country") from e
×
63

64
    if not validator(id_code):
1✔
65
        # Find country name from Countries attributes
66
        cty = next(name for name, value in iter(Countries.__dict__.items()) if value == country)
1!
67
        raise InvalidIdCode(f"ID code '{id_code}' is not valid for {cty.capitalize()}")
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc