Skip to content
This repository has been archived by the owner on Jan 8, 2025. It is now read-only.

Commit

Permalink
Fix #48 - implement 3 identity numbers for Greece (#197)
Browse files Browse the repository at this point in the history
  • Loading branch information
microdataxyz authored Feb 23, 2023
1 parent 0d3be1b commit 5331b1c
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 1 deletion.
89 changes: 89 additions & 0 deletions idnumbers/nationalid/GRC.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import re
from types import SimpleNamespace
from .util import validate_regexp, weighted_modulus_digit, modulus_overflow_mod10


class OldIdentityCard:
"""
Greece Identity Card, the old one.
https://en.wikipedia.org/wiki/National_identification_number#Greece
"""
METADATA = SimpleNamespace(**{
'iso3166_alpha2': 'GR',
'min_length': 7,
'max_length': 7,
'parsable': False,
'checksum': False,
'regexp': re.compile(r'^[ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ]-?\d{6}$')
})

@staticmethod
def validate(id_number: str) -> bool:
"""
Validate with regexp
"""
return validate_regexp(id_number, OldIdentityCard.METADATA.regexp)


class IdentityCard:
"""
Greece Identity Card, the new one.
https://en.wikipedia.org/wiki/National_identification_number#Greece
"""
METADATA = SimpleNamespace(**{
'iso3166_alpha2': 'GR',
'min_length': 7,
'max_length': 7,
'parsable': False,
'checksum': False,
'regexp': re.compile(r'^[ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩABEZHIKMNOPTYX]{2}-?\d{6}$')
# They are two different char set, the former is Greek alphabet, the latter is Latin alphabet
})

@staticmethod
def validate(id_number: str) -> bool:
"""
Validate with regexp
"""
return validate_regexp(id_number, IdentityCard.METADATA.regexp)


class TaxIdentityNumber:
"""
Greece Tax Identity Number, AFM - ΑΦΜ - Αριθμός Φορολογικού Μητρώου - Tax Registry Number
https://en.wikipedia.org/wiki/National_identification_number#Greece
"""
METADATA = SimpleNamespace(**{
'iso3166_alpha2': 'GR',
'min_length': 9,
'max_length': 9,
'parsable': False,
'checksum': True,
'regexp': re.compile(r'^\d{9}$')
})

MULTIPLIER = [256, 128, 64, 32, 16, 8, 4, 2]

@staticmethod
def validate(id_number: str) -> bool:
"""
Validate with regexp
"""
return TaxIdentityNumber.checksum(id_number)

@staticmethod
def checksum(id_number: str) -> bool:
"""
ref: https://stackoverflow.com/a/4377376
"""
if not validate_regexp(id_number, TaxIdentityNumber.METADATA.regexp):
return False
numbers = [int(char) for char in id_number]
modulus = modulus_overflow_mod10(weighted_modulus_digit(numbers[0:-1], TaxIdentityNumber.MULTIPLIER, 11, True))
return numbers[-1] == modulus


NationalID = IdentityCard
"""
alias of IdentityCard
"""
15 changes: 15 additions & 0 deletions tests/nationalid/test_GRC.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from unittest import TestCase

from idnumbers.nationalid import GRC


class TestGRCNationalInsuranceNumberValidation(TestCase):
def test_normal_case(self):
self.assertTrue(GRC.OldIdentityCard.validate('Φ-123456'))
self.assertTrue(GRC.IdentityCard.validate('ΦA-123456'))
self.assertTrue(GRC.TaxIdentityNumber.validate('355827182'))

def test_error_case(self):
self.assertFalse(GRC.OldIdentityCard.validate('A-123456')) # test with latin
self.assertFalse(GRC.IdentityCard.validate('A-123456')) # wrong digits
self.assertFalse(GRC.TaxIdentityNumber.validate('355827181'))
2 changes: 1 addition & 1 deletion tests/nationalid/test_HUN.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from unittest import TestCase, main
from unittest import TestCase

from idnumbers.nationalid import HUN

Expand Down

0 comments on commit 5331b1c

Please sign in to comment.