Last active
April 25, 2019 20:11
-
-
Save ultrafunkamsterdam/9154360051792f059a360a480d4a6e01 to your computer and use it in GitHub Desktop.
IBAN class (NL focussed) with no dependencies or imports
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class IBAN: | |
def __init__(self, iban: str): | |
if len(iban) < 15: | |
raise ValueError('not a valid IBAN (too short or not in format CC00BANK01234567). got: {}'.format(iban)) | |
self._iban = iban | |
self.get() | |
@staticmethod | |
def getMod97(iban_im_format): | |
return int(''.join(str(ord(v)-55 if v.isalpha() else v) for v in iban_im_format)) | |
@property | |
def checksum(self): | |
chk = 98 - (self.getMod97(self.im_format) % 97) | |
return "0" + str(chk) if len(str(chk)) == 1 else str(chk) | |
@property | |
def bank_code(self): | |
return self._iban[4:8] | |
@property | |
def bank_code_int(self): | |
return self.getMod97(self.bank_code) | |
@property | |
def country_code(self): | |
return self._iban[:2] | |
@property | |
def country_code_int(self): | |
return self.getMod97(self.country_code) | |
@property | |
def account_number(self): | |
ban = self._iban[8:] | |
while len(ban) < 10: | |
ban = '0' + ban | |
self._iban = self._iban[:8] + ban | |
return self._iban[8:] | |
@property | |
def im_format(self): | |
ib = self.bank_code + self.account_number + self.country_code | |
return ib + '00' | |
@property | |
def valid(self): | |
return self.getMod97(self._iban[4:] + self._iban[:4]) % 97 == 1 | |
def get(self): | |
self._iban = self.country_code + self.checksum + self.bank_code + self.account_number | |
return self._iban | |
@classmethod | |
def fromLegacyBankAccount(cls, bank_account_number, country_code="NL", bank_code="ABNA"): | |
ban = str(bank_account_number) | |
return cls(country_code + '00' + bank_code + ban) | |
def __str__(self): | |
return self.get().replace(' ','').strip() | |
def __repr__(self): | |
return f'<IBAN ({"valid" if self.valid else "invalid"}) ({self.country_code} {self.checksum} {self.bank_code} {self.account_number})>' | |
def generate_iban(bankcode="ABNA", countrycode="NL"): | |
while True: | |
nums = [random.randint(1, 9) for _ in range(9)] | |
p11_sum = sum([operator.mul(a, b) for a, b in zip(range(1, 10), nums)]) / 10 | |
p11_outcome = p11_sum % 1 == 0 | |
if p11_outcome is True: | |
# We got ourselves a valid dutch bank account. now transform this into IBAN | |
return IBAN.fromLegacyBankAccount(''.join(str(n) for n in nums), country_code=countrycode, bank_code=bankcode) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment