a life less ordinary ?

the egghead diaries


27 Kommentare

Tag 17997, IBAN-Massaker

Zunächst habe ich natürlich geflucht wie ein Rohrspatz. Dann habe ich den Herrn Prellbock von der Bank angerufen, er möge mir bitte die IBANs meiner Konten nennen weil ich sie nirgens finde. Während er murmelt und ich ihn wild in seinen Masken rumclicken höre, finde ich die IBANs bei der Spasskasse durch Zufall selber … sie werden als Tooltip angezeigt, wenn man lange genug mit der Maus auf der Kontonummer verharrt. Sonst nirgendwo. Hätte ich schon wieder eine Bombe in den Laden werfen und den überlebenden Rest der Arschlöcher nach Sibirien verschiffen lassen mögen. Als ich das dem Prellbock erklärt hatte damit auch er endlich weiß wo er IBANs finden kann, wünschten wir uns frohe Weihnachten.

Dann habe ich rausgefunden, dass das ja ganz einfach ist, und mich schlagartig beruhigt. DE?? + BLZ (8-stellig) + Kto (10-stellig, führende Nullen). Das sind immerhin 20 der 22 Stellen die ich sofort weiß. Ries’ng’schicht, fast am Ziel ! Der Rest kann doch nicht so schwer sein ?

Natürlich nicht, denn für die beiden Fragenzeichen muss man nur eine 24-stellige Zahl bilden aus der BLZ, der Kontonummer, hinten noch die in Zahlen umgerechnete Länderkennung und zwei Nullen dranstellen, das modulo 97 nehmen und von 98 abziehen. Total easy !

Und als mathematisches Scharnier ist das eins der einfachsten Dinge, das ich schon morgens auf dem Thron im gekachelten Herrenzimmer spaßeshalber mache, wenn die Zeitung noch nicht da ist, ich noch kräftig drücke, und bereits die Anzahl Atome in einem Muffin im Kopf ausgerechnet habe.

Als ich fünf Pfund leichter und meiner eigenen IBANs bewusst von Thron stieg klingelte das Telefon. Also legte ich die Reichsinsignien Badelatschen und Kaffeebecher an und gewährte gutgelaunt eine Audienz. Jedoch ist scheinbar nicht jeder ein mathematisches Scharnier und die Audienz verlief ein wenig zäh. Zeit also für einen schnellen hack. Läuft ab SQL2000. Liefert die elektronische IBAN und die menschenlesbare dazu.

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[IBANDE]') 
  and xtype in (N'FN', N'IF', N'TF'))
  drop function [dbo].[IBANDE]
GO

CREATE FUNCTION IBANDE (
  @nKonto           numeric(35,0)
, @nBLZ             numeric(35,0)
, @szCountryCodeDE  nvarchar(2)
) 
returns @tblIBAN table (
  szIBAN            nvarchar(22)
, szIBANChopped     nvarchar(27)
) as
BEGIN
--  --------------------------------------------------------------------------------
--  IBAN ermitteln
--  ausschliesslich für deutsche Konten 
--
--  Auslaendische Konten erfordern andere Laenderkennungen und können bis zu sieben 
--  zusaetzliche Stellen haben
--
--  Result:
--  IBAN als string
--  IBAN als lesbarer string
--  
--  23.12.13  castagir angelegt
--  --------------------------------------------------------------------------------

  declare @nCountryCodeDE int             ; select @nCountryCodeDE = 0
  declare @nBBAN numeric(35,0)            ; select @nBBAN = 0
  declare @nTemp numeric(35,0)            ; select @nTemp = 0
  declare @nCheckDigits int               ; select @nCheckDigits = 0
  declare @szIBAN nvarchar(22)            ; select @szIBAN = ''

  -- Abfangen zumindest des groebsten Unfugs bei der Eingabe
  if UPPER(@szCountryCodeDE) = 'DE' and @nBLZ > 0 and @nKonto > 0 and len(@nBLZ) = 8 and len(@nKonto) <= 10 
    begin
      -- BBAN: 8-stellige Bankleitzahl plus 10-stellige Kontonummer
      -- Kontonummer ggf. von vorne mit 0 aufgefüllt
      -- --------------------------------------------------------------------------------
      select  @nBBAN = @nBLZ * 10000000000 + @nKonto

      -- numerischer Laendercode: Position des Buchstabens im Alphabet + 9, 
      -- zusammengefasst zu einer Zahl
      -- 'D': Vierter Buchstabe + 9 = 13
      -- 'E': Fünfter Buchstabe + 9 = 14
      -- --------------------------------------------------------------------------------
      select @nCountryCodeDE = 1314

      -- Berechnung der beiden Pruefziffern:
      -- (BBAN + numerischen Laendercode + 00) modulo 97 ermitteln, und von 98 abziehen
        -- --------------------------------------------------------------------------------
      select  @nTemp = (@nBBAN * 10000 + @nCountryCodeDE) * 100
      select  @nCheckDigits = 98 - (@nTemp % 97)

      -- Ausgabe: Laendercode + Pruefziffern (ggf. aufgefuellt mit fuehrender 0) + BBAN
      -- --------------------------------------------------------------------------------
      select @szIBAN = @szCountryCodeDE
                     + replicate('0', 2-len(@nCheckDigits))
                     + convert(nvarchar(2), @nCheckDigits)
                     + convert(nvarchar(18), @nBBAN) 

      insert into @tblIBAN
      select 
        @szIBAN 
      , substring(@szIBAN,  1, 4) + ' ' + substring(@szIBAN,  5, 4) + ' ' 
      + substring(@szIBAN,  9, 4) + ' ' + substring(@szIBAN, 13, 4) + ' ' 
      + substring(@szIBAN, 17, 4) + ' ' + substring(@szIBAN, 21, 4) 
    end

  return
END


select * from dbo.IBANDE(1234567890, 70010000, 'DE')

szIBAN                 szIBANChopped
---------------------- ---------------------------
DE02700100001234567890 DE02 7001 0000 1234 5678 90

Natürlich ist da ein winziger hack drin, der jeden dritten Überweisungsbetrag auf eins meiner Konten auf den Caiman-Inseln umleitet – aber ich muss ja schließlich auch von irgendwas leben.

Und jetzt will ich frühstücken. Viel. Damit ich morgen auf den Thron kann. Um neue IBANs zu berechnen. Im Kopf natürlich – in SQL kann’s ja fast jeder.