Skip to content

Instantly share code, notes, and snippets.

@martijnluinstra
Last active October 10, 2017 01:20
Show Gist options
  • Save martijnluinstra/de9959d2b958635b1e60f8bd25cdb1dd to your computer and use it in GitHub Desktop.
Save martijnluinstra/de9959d2b958635b1e60f8bd25cdb1dd to your computer and use it in GitHub Desktop.
Dutch IBAN generator
"""
Python 3 Generator for Dutch IBANs.
Should be equivalent to gist.github.com/martijnluinstra/9ca0f62b9ddc01288be8a6072d29b029
Demo: projects.martijnluinstra.nl/iban/
Copyright (c) 2017 Martijn Luinstra
"""
import functools
import operator
def iban_to_number(iban):
""" Converts IBAN to the decimal representation as used for validation """
code = iban[4:] + iban[:4]
def generate(code):
for x in code:
try:
yield str(int(x))
except:
yield str(ord(x) - 55)
return int(''.join(generate(code.upper())))
def validate_iban(iban):
""" Validates IBAN based on checksum """
return iban_to_number(iban) % 97 == 1
def generate_account_number(unchecked):
""" Generates elfproef-valid account number with based on numberic string """
length = len(unchecked) + 1
total = sum(int(x) * (length - idx) for idx, x in enumerate(unchecked))
check = 11 - (total % 11)
if check > 0 and check < 10:
return unchecked + str(check)
# Did not find a number that passes the elfproef, increase unchecked and try again
return generate_account_number(str(int(unchecked) + 1))
def generate_iban(seed, bank_code=None, country='NL', account_length=9):
""" Generates realistic Dutch IBAN based on seed and (list of) bank code(s) """
codes = (ord(x) for x in seed.upper())
number = 1
for idx, x in enumerate(codes):
number *= x + idx
number = str(number).strip('0')
account = generate_account_number(number[:account_length-1])
account = '{:0>{}}'.format(account, account_length + 1)
if not bank_code:
bank_code = 'BANK'
elif isinstance(bank_code, list):
idx = (ord(number[0]) * ord(number[-1])) % len(bank_code)
bank_code = bank_code[idx]
remainder = iban_to_number(''.join((country, '00', bank_code, account))) % 97
check = '{:0>2}'.format(98 - remainder)
return ''.join((country, check, bank_code, account))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment