Skip to content

Instantly share code, notes, and snippets.

@ultrafunkamsterdam
Last active April 25, 2019 20:11
Show Gist options
  • Save ultrafunkamsterdam/9154360051792f059a360a480d4a6e01 to your computer and use it in GitHub Desktop.
Save ultrafunkamsterdam/9154360051792f059a360a480d4a6e01 to your computer and use it in GitHub Desktop.
IBAN class (NL focussed) with no dependencies or imports
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