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

Commit c1c3c4c

Browse files
authored
Fix #9 - implement Bahrain personal number without the checksum (#215)
1 parent b1d2238 commit c1c3c4c

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

idnumbers/nationalid/BHR.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import re
2+
from types import SimpleNamespace
3+
from typing import Optional, TypedDict
4+
from .util import CHECK_DIGIT
5+
6+
7+
class ParseResult(TypedDict):
8+
yymm: str
9+
"""birthday of this ID"""
10+
sn: str
11+
"""serial number"""
12+
checksum: CHECK_DIGIT
13+
"""checksum"""
14+
15+
16+
class PersonalNumber:
17+
"""
18+
Bahrain Personal Number, Identification Card Number, Arabic: الرقم الشخصي
19+
https://en.wikipedia.org/wiki/National_identification_number#Bahrain
20+
* According to the doc, we can know it has checksum algorithm. But we cannot find it.
21+
"""
22+
METADATA = SimpleNamespace(**{
23+
'iso3166_alpha2': 'BH',
24+
'min_length': 9,
25+
'max_length': 9,
26+
'parsable': True,
27+
'checksum': False,
28+
'regexp': re.compile(r'^(?P<yymm>\d{2}(?:0[1-9]|1[012]))'
29+
r'(?P<sn>\d{4})'
30+
r'(?P<checksum>\d)$')
31+
})
32+
33+
@staticmethod
34+
def validate(id_number: str) -> bool:
35+
"""
36+
Validate the civil number
37+
"""
38+
if not id_number:
39+
return False
40+
41+
if not isinstance(id_number, str):
42+
id_number = repr(id_number)
43+
return PersonalNumber.parse(id_number) is not None
44+
45+
@staticmethod
46+
def parse(id_number: str) -> Optional[ParseResult]:
47+
"""
48+
parse the id number
49+
"""
50+
match_obj = PersonalNumber.METADATA.regexp.match(id_number)
51+
if not match_obj:
52+
return None
53+
54+
# TODO: find and implement checksum
55+
return {
56+
'yymm': match_obj.group('yymm'),
57+
'sn': match_obj.group('sn'),
58+
'checksum': int(match_obj.group('checksum'))
59+
}
60+
61+
62+
NationalID = PersonalNumber
63+
"""alias of PersonalNumber"""

tests/nationalid/test_BHR.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from unittest import TestCase
2+
3+
from idnumbers.nationalid import BHR
4+
5+
6+
class TestBHRValidation(TestCase):
7+
def test_normal_case(self):
8+
self.assertTrue(BHR.NationalID.validate('051108109'))
9+
10+
def test_error_case(self):
11+
self.assertFalse(BHR.NationalID.validate('053108109'))
12+
13+
def test_parse(self):
14+
result = BHR.NationalID.parse('051108109')
15+
self.assertEqual('0511', result['yymm'])
16+
self.assertEqual('0810', result['sn'])
17+
self.assertEqual(9, result['checksum'])

0 commit comments

Comments
 (0)