1# bic.py - functions for handling ISO 9362 Business identifier codes 2# 3# Copyright (C) 2015 Lifealike Ltd 4# Copyright (C) 2017-2018 Arthur de Jong 5# 6# This library is free software; you can redistribute it and/or 7# modify it under the terms of the GNU Lesser General Public 8# License as published by the Free Software Foundation; either 9# version 2.1 of the License, or (at your option) any later version. 10# 11# This library is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14# Lesser General Public License for more details. 15# 16# You should have received a copy of the GNU Lesser General Public 17# License along with this library; if not, write to the Free Software 18# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19# 02110-1301 USA 20 21"""BIC (ISO 9362 Business identifier codes). 22 23An ISO 9362 identifier (also: BIC, BEI, or SWIFT code) uniquely 24identifies an institution. They are commonly used to route financial 25transactions. 26 27The code consists of a 4 letter institution code, a 2 letter country code, 28and a 2 character location code, optionally followed by a three character 29branch code. 30 31>>> validate('AGRIFRPP882') 32'AGRIFRPP882' 33>>> validate('ABNA BE 2A') 34'ABNABE2A' 35>>> validate('AGRIFRPP') 36'AGRIFRPP' 37>>> validate('AGRIFRPP8') 38Traceback (most recent call last): 39 ... 40InvalidLength: .. 41>>> validate('AGRIF2PP') # country code can't contain digits 42Traceback (most recent call last): 43 ... 44InvalidFormat: .. 45>>> format('agriFRPP') # conventionally caps 46'AGRIFRPP' 47 48""" 49 50import re 51 52from stdnum.exceptions import * 53from stdnum.util import clean 54 55 56_bic_re = re.compile(r'^[A-Z]{6}[0-9A-Z]{2}([0-9A-Z]{3})?$') 57 58 59def compact(number): 60 """Convert the number to the minimal representation. This strips the 61 number of any surrounding whitespace.""" 62 return clean(number, ' -').strip().upper() 63 64 65def validate(number): 66 """Check if the number is a valid routing number. This checks the length 67 and characters in each position.""" 68 number = compact(number) 69 if len(number) not in (8, 11): 70 raise InvalidLength() 71 match = _bic_re.search(number) 72 if not match: 73 raise InvalidFormat() 74 return number 75 76 77def is_valid(number): 78 """Check if the number provided is a valid BIC.""" 79 try: 80 return bool(validate(number)) 81 except ValidationError: 82 return False 83 84 85def format(number): 86 """Reformat the number to the standard presentation format.""" 87 return compact(number) 88