diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2022-11-13 15:53:56 +0100 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2022-11-13 16:47:04 +0100 |
commit | fa62ea3f7862fd000bb11b62e338ff25bfc3af7d (patch) | |
tree | e5b0b65ef963f7576a144f7f9751605b632dd02c | |
parent | feccaffeb393e8e7232afd71d515368da524ba50 (diff) |
Add Pakistani ID card number
Based on the implementation provided by Quantum Novice (Syed Haseeb
Shah).
Closes https://github.com/arthurdejong/python-stdnum/pull/306
Closes https://github.com/arthurdejong/python-stdnum/issues/304
-rw-r--r-- | stdnum/pk/__init__.py | 21 | ||||
-rw-r--r-- | stdnum/pk/cnic.py | 112 | ||||
-rw-r--r-- | tests/test_pk_cnic.doctest | 40 |
3 files changed, 173 insertions, 0 deletions
diff --git a/stdnum/pk/__init__.py b/stdnum/pk/__init__.py new file mode 100644 index 0000000..163ca84 --- /dev/null +++ b/stdnum/pk/__init__.py @@ -0,0 +1,21 @@ +# __init__.py - collection of Pakistani numbers +# coding: utf-8 +# +# Copyright (C) 2022 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +"""Collection of Pakistani numbers.""" diff --git a/stdnum/pk/cnic.py b/stdnum/pk/cnic.py new file mode 100644 index 0000000..cd1381f --- /dev/null +++ b/stdnum/pk/cnic.py @@ -0,0 +1,112 @@ +# cnic.py - functions for handling Pakistani CNIC numbers +# coding: utf-8 +# +# Copyright (C) 2022 Syed Haseeb Shah +# Copyright (C) 2022 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +"""CNIC number (Pakistani Computerised National Identity Card number). + +The CNIC (Computerised National Identity Card, قومی شناختی کارڈ) or SNIC +(Smart National Identity Card) is issued by by Pakistan's NADRA (National +Database and Registration Authority) to citizens of 18 years or older. + +The number consists of 13 digits and encodes the person's locality (5 +digits), followed by 7 digit serial number an a single digit indicating +gender. + +More Information: + +* https://en.wikipedia.org/wiki/CNIC_(Pakistan) +* https://www.nadra.gov.pk/identity/identity-cnic/ + +>>> validate('34201-0891231-8') +'3420108912318' +>>> validate('42201-0397640-8') +'4220103976408' +>>> get_gender('42201-0397640-8') +'F' +>>> get_province('42201-0397640-8') +'Sindh' +>>> format('3420108912318') +'34201-0891231-8' +""" + +from stdnum.exceptions import * +from stdnum.util import clean, isdigits + + +def compact(number): + """Convert the number to the minimal representation. This strips the + number of any valid separators and removes surrounding whitespace.""" + return clean(number, '-').strip() + + +def get_gender(number): + """Get the person's birth gender ('M' or 'F').""" + number = compact(number) + if number[-1] in '13579': + return 'M' + elif number[-1] in '2468': + return 'F' + + +# Valid Province IDs +PROVINCES = { + '1': 'Khyber Pakhtunkhwa', + '2': 'FATA', + '3': 'Punjab', + '4': 'Sindh', + '5': 'Balochistan', + '6': 'Islamabad', + '7': 'Gilgit-Baltistan', +} + + +def get_province(number): + """Get the person's birth gender ('M' or 'F').""" + number = compact(number) + return PROVINCES.get(number[0]) + + +def validate(number): + """Check if the number is a valid CNIC. This checks the length, formatting + and some digits.""" + number = compact(number) + if not isdigits(number): + raise InvalidFormat() + if len(number) != 13: + raise InvalidLength() + if not get_gender(number): + raise InvalidComponent() + if not get_province(number): + raise InvalidComponent() + return number + + +def is_valid(number): + """Check if the number is a valid CNIC.""" + try: + return bool(validate(number)) + except ValidationError: + return False + + +def format(number): + """Reformat the number to the standard presentation format.""" + number = compact(number) + return '-'.join((number[:5], number[5:12], number[12:])) diff --git a/tests/test_pk_cnic.doctest b/tests/test_pk_cnic.doctest new file mode 100644 index 0000000..8b2d038 --- /dev/null +++ b/tests/test_pk_cnic.doctest @@ -0,0 +1,40 @@ +test_pk_cnic.doctest - more detailed doctests for stdnum.pk.cnic + +Copyright (C) 2022 Arthur de Jong + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA + + +This file contains more detailed doctests for the stdnum.pk.cnic module. + +>>> from stdnum.pk import cnic + + +>>> cnic.validate('34201-0891231-8') +'3420108912318' +>>> cnic.validate('34201-0891231-0') # invalid gender +Traceback (most recent call last): + ... +InvalidComponent: ... +>>> cnic.validate('94201-0891231-8') # invalid province +Traceback (most recent call last): + ... +InvalidComponent: ... + +>>> cnic.get_gender('34201-0891231-8') +'F' +>>> cnic.get_gender('34201-0891231-9') +'M' |