Last active
December 20, 2015 09:19
-
-
Save lorenzhs/6106558 to your computer and use it in GitHub Desktop.
Kontonummer / BLZ to IBAN / BIC converter
This file contains 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
# 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