Skip to content

Instantly share code, notes, and snippets.

@lorenzhs
Last active December 20, 2015 09:19
Show Gist options
  • Save lorenzhs/6106558 to your computer and use it in GitHub Desktop.
Save lorenzhs/6106558 to your computer and use it in GitHub Desktop.
Kontonummer / BLZ to IBAN / BIC converter
# coding: utf-8
# author: Lorenz H-S (github.com/lorenzhs)
# license: 3-clause BSD
import re
import urllib2
from datetime import date
import codecs
from collections import defaultdict
import sys
def knrBlzToIBAN(knr, blz):
bban = int(str(blz) + str(knr).zfill(10) + "131400") # 1314 = DE
remainder = 98 - (bban % 97)
checksum = str(remainder).zfill(2)
iban = "DE" + checksum + str(blz) + str(knr).zfill(10)
return iban
def downloadLatestBlzBICTable(outfilename):
BASE_URL = "http://www.bundesbank.de"
overview_url = "{base}/Redaktion/DE/Standardartikel/Kerngeschaeftsfelder/Unbarer_Zahlungsverkehr/bankleitzahlen_download.html".format(base=BASE_URL)
datafile_regexp = re.compile('<a href="(.*/blz_([0-9]{4})_([0-9]{2})_([0-9]{2})_txt\.txt.*)"')
print 'Dowloading list of available tables...'
overview = urllib2.urlopen(overview_url).read()
datafiles = datafile_regexp.findall(overview)
max_date = date(1970,1,1)
latest_url = None
for (url, year, month, day) in datafiles:
curr_date = date(int(year), int(month), int(day))
if curr_date > max_date and curr_date <= date.today():
latest_url = url
if latest_url is None:
print "Error: No presently valid data files found"
else:
latest_url = BASE_URL + latest_url
print "Downloading table from", latest_url,
sys.stdout.flush()
data = urllib2.urlopen(latest_url).read()
print "done."
with open(outfilename, 'w') as outfile:
outfile.write(data)
def parseBlzBICTable(infilename):
with codecs.open(infilename, 'r', 'iso-8859-1') as infile:
data = infile.readlines()
lines = [line.strip() for line in data]
blzDir = defaultdict(list)
for line in lines:
blz = int(line[:8])
hauptniederlassung = bool(int(line[8]))
#if not hauptniederlassung:
# continue
bank_name = line[9:66].strip()
plz = int(line[67:72])
location = line[72:106].strip()
branch_name = line[107:134].strip()
bic = line[139:150].strip()
if bic != '':
blzDir[blz].append((bic, hauptniederlassung, bank_name, plz, location, branch_name))
return blzDir
def writeBlzBICTableToHumanReadableFormat(blzDir, outfilename):
with codecs.open(outfilename, 'w', 'utf-8') as f:
for (key, values) in blzDir.iteritems():
f.write(unicode(key))
if len(values) > 1:
f.write('\n')
for val in values:
f.write(u'\t' + u'\t'.join([unicode(v) for v in val]) + '\n')
if __name__ == '__main__':
downloadLatestBlzBICTable('blzbictable')
print 'parsing table...'
blzDir = parseBlzBICTable('blzbictable')
print 'parsed', len(blzDir), 'banks\' details'
writeBlzBICTableToHumanReadableFormat(blzDir, 'blz_to_bic')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment