diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2017-08-26 22:37:17 +0200 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2017-08-26 23:21:58 +0200 |
commit | efd2eb98ed51c0866b4f206e93cbc1bc1691ee5a (patch) | |
tree | 39bae7b9edfd81ed27a362da328dbd4412f593d6 | |
parent | b8e12d631eec0b000f74d813f6a7d570187c67f5 (diff) |
Add Canadian Social Insurance Number (SIN)
-rw-r--r-- | stdnum/ca/__init__.py | 21 | ||||
-rw-r--r-- | stdnum/ca/sin.py | 80 |
2 files changed, 101 insertions, 0 deletions
diff --git a/stdnum/ca/__init__.py b/stdnum/ca/__init__.py new file mode 100644 index 0000000..bb4db36 --- /dev/null +++ b/stdnum/ca/__init__.py @@ -0,0 +1,21 @@ +# __init__.py - collection of Canadian numbers +# coding: utf-8 +# +# Copyright (C) 2017 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 Canadian numbers.""" diff --git a/stdnum/ca/sin.py b/stdnum/ca/sin.py new file mode 100644 index 0000000..59e8713 --- /dev/null +++ b/stdnum/ca/sin.py @@ -0,0 +1,80 @@ +# sin.py - functions for handling Canadian Social Insurance Numbers (SINs) +# +# Copyright (C) 2017 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 + +"""SIN (Canadian Social Insurance Number). + +The Social Insurance Number (SIN) is a 9-digit identifier issued to +individuals for various government programs. SINs that begin with a 9 are +issued to temporary workers who are neither Canadian citizens nor permanent +residents. + +More information: + +* https://www.canada.ca/en/employment-social-development/services/sin.html +* https://en.wikipedia.org/wiki/Social_Insurance_Number + +>>> validate('123-456-782') +'123456782' +>>> validate('999-999-999') +Traceback (most recent call last): + ... +InvalidChecksum: ... +>>> validate('12345678Z') +Traceback (most recent call last): + ... +InvalidFormat: ... +>>> format('123456782') +'123-456-782' +""" + +from stdnum import luhn +from stdnum.exceptions import * +from stdnum.util import clean + + +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 validate(number): + """Checks to see if the number provided is a valid SIN. This checks the + length, formatting and check digit.""" + number = compact(number) + if len(number) != 9: + raise InvalidLength() + if not number.isdigit(): + raise InvalidFormat() + return luhn.validate(number) + + +def is_valid(number): + """Checks to see if the number provided is a valid SIN. This checks the + length, formatting and check digit.""" + try: + return bool(validate(number)) + except ValidationError: + return False + + +def format(number): + """Reformat the passed number to the standard format.""" + number = compact(number) + return '-'.join((number[0:3], number[3:6], number[6:])) |