IBAN validator as a dITo project

Author: ulrichmerkel@web.de (ulrich-merkel)

in europe, we will have IBAN numbers for "international" money transactions as a must shortly.

So databases have to be enhanced to hold this up to 31 characters (for Malta) long string.
As the documentation says; only banks are entitled to generate IBAN numbers,
because they may have special ideas how to compose this number:

Padding accounts or using sub-account numbers is one of the points they may want to have their own ideas.

Unfortunately, this will stop us to generate the IBAN from the data already held in our databases and we may have to face manual data entry

And because this Monster holds in Position3 and 4 a check-sum, one needs a validation routine to check data input perhaps written in uniface ??

 

Is there any interest to join efforts to provide a general IBAN validator routine here on uniface.info  ??

 

I think, it should be some dITo type of task (not "professional" because it will be free of charge), so : ANY VOLUNTEERS to join the band?

Uli

12 Comments

  1. Allready done with UnifAce for years.
    We do have a generator and a check routine for IBAN

    For a 99% proof solution you need to use special software of the banks involved. Or one can use CSV files to send  BBAN and BIC (account number and banc code) to a bank association which will return the IBAN.
    But even htis associations will not guarantee 100% proof IBAN

    So to be sure, that the IBAN is right, you have to ask your customers

    Ingo

     

     


    Author: istiller (i2stiller@gmx.de)
  2. You cannot generate an IBAN for a Dutch bank account number.

    A joint effort for an international IBAN validator seems like a good plan.


    Author: Theo Neeskens (tneeskens@itblockz.nl)
  3. Hi Theo

    If you know the 4 characters för the bank identification, it should be possible:

    http://nl.wikipedia.org/wiki/International_Bank_Account_Number#Nederland

    http://www.ibannl.org/iban_check.php

    And the "bank code" looks like the 4 first characters of the BIC

    Ingo

     

     

     

     

     


    Author: istiller (i2stiller@gmx.de)

  4. Hi Theo

    If you know the 4 characters f?r the bank identification, it should be possible:

    http://nl.wikipedia.org/wiki/International_Bank_Account_Number#Nederland

    http://www.ibannl.org/iban_check.php

    And the "bank code" looks like the 4 first characters of the BIC

    Ingo


    That is correct Ingo. But most of the time the bank(code) has not been stored, since it was not needed. But there is a conversion service available in Holland. It is free up to quite large numbers of bank account number, and when you go over that it still doesn't cost a fortune. Unfortunately no online webservice is available. You need to upload a file with account numbers and you will get a file with Iban's back.


    Author: Theo Neeskens (tneeskens@itblockz.nl)
  5. Hi all,

    we have IBAN check and generate procedure, but this is only for CZECH bank accounts. I am affraid, each country has its own way, how to generate IBAN from account number and bank code. CZECH accounts for exemple don't use SWIFT/BIC.

    BTW, IBAN is usualy displayd with spaces between each 4 characters groups. It is not possible to use Uniface dispaly format for this, because IBAN is too long for this. (Strange, isn't it?)

     


    Author: st_cyz (cyz@fullsys.cz)
  6. ... and IBAN is a string. But I think you can use just the format trigger to split it up and use $replace in the deformat trigger to get rid of the spaces..

    Hi Stanislav,

    AFAIK, the validation uses a modulo 97 for a very long number (expanded up to 33 digits) which has to be 1.

    Have you implemented this in uniface?

    Perhaps you want to share your code with us?

    Uli


    Author: ulrich-merkel (ulrichmerkel@web.de)
  7. Yes, modulo 97 is possible with UnifAce

    We did implement this years ago*). And we did generate and check IBAN for all countries.
    Okay, not 100% proofed. But for a suggestion to send to the customers this will do its job

    Ingo

    *) You should know this >:(


    Author: istiller (i2stiller@gmx.de)
  8. The code is more then 8 years old, so details are forgotten :-)  I only translated messages. As said before, this is only for CZ IBAN. Perhaps, someone can improve it to support all countries.

    Regards Stanislav

    entry CHK_IBAN

    params
      string P_IBAN :in
      string P_ERR  :out
    endparams

    variables
      numeric    V_STAV, V_C, V_Z, V_POMN, V_POMN1, V_DELKA, V_N, V_POZICE
      string     V_IBAN, V_POMC, V_POMC1, V_KONTR_NUM, V_STAT
      boolean    V_END
    endvariables

    if (P_IBAN = "")
      P_ERR = "Empty IBAN."
      return -1
    endif

    V_STAT = P_IBAN[1,2]
    if (V_STAT != "CZ")
      P_ERR = "No CZ IBAN."
      return -1
    endif

    ; "C" & "Z"
    V_C = 12
    V_Z = 35

    V_KONTR_NUM = P_IBAN[3,4]
    V_IBAN      = P_IBAN[5]
    V_POMC      = "%%V_IBAN%%%%%V_C%%%%%V_Z%%%%%V_KONTR_NUM%%%"

    ;modulo 97


    V_POZICE = 9
    V_POMC1  = V_POMC[1:V_POZICE]
    V_POZICE = V_POZICE + 1
    V_END = 0
    repeat
      V_POMN  = $number(V_POMC1)
      V_POMN1 = $number(V_POMC1)
      V_POMN  = V_POMN / 97
      V_POMN  = V_POMN[trunc]
      V_POMN  = V_POMN * 97
      V_POMN  = V_POMN1 - V_POMN

      V_POMC1  = "%%V_POMN%%%"
      if (V_END) break
      length V_POMC1
      if ($result = 2)
        V_POMC1 = V_POMC[V_POZICE:7]
        V_POZICE = V_POZICE + 7
        V_POMC1 = "%%V_POMN%%V_POMC1%%%"
      else
        V_POMC1 = V_POMC[V_POZICE:8]
        V_POZICE = V_POZICE + 8
        V_POMC1 = "0%%V_POMN%%V_POMC1%%%"
      endif

      length V_POMC1
      if ($result < 9) V_END = 1

      V_N = V_N + 1
    until (V_N < 0)

    if (V_POMC1 != "1")
      P_ERR ="Invalid IBAN."
      return -1
    endif

    return 0
     


    Author: st_cyz (cyz@fullsys.cz)
  9. Hi

    Could it be, that the czech IBAN only contain digits (and of cource "SZ" at the front) ?
    If other countries do have characters in the bank code or the account number, you have to substitute them by there numbers.

    A=10,B=11,...,Z=35

    Take in account, that the "IBAN" could be longer then 35 characters when replacing the characters

     

    So

    1. Move characters 1 to4 (country and check digits) to the end of the IBAN.
         If you want to generate a check number, use "00" instead of the check number.
           "CH00002300A1023502601"  -> "002300A1023502601CH00"

    2. Replace characters by numbers
           "002300A1023502601CH00"->"002300101023502601121700"

    3. Calculate the modulo 97 of the whole "number" *)
        Substract the result from 98, giving the result/check digit
           002300101023502601121700 : 97
           Remainder = 88
           98 – 88 = 10

       *) If a programm language could not handle such big numbers: One can split the modulo 97 operation into parts of 9 digits.
            Stanislav did the right "trick" :-)
     

    4. a) If you check a give number, the result should by 1
        b) If you generate ("00" at the end) , the result is the check digit 

    4. Take the original IBAN and replace the characters at position 3 and 4 by the check digit
          "CH00002300A1023502601"-> "CH10002300A1023502601"

     

    Here a dokument, which describes the steps (german, but readable for other, as there is a lot of math :-)  )

    http://www.pruefziffernberechnung.de/Originaldokumente/IBAN/Prufziffer_07.00.pdf
    (chapter 2.2/side 6 ff)

    Ingo

     


    Author: istiller (i2stiller@gmx.de)
  10. IBAN is max 34 characters.

    pos 1 & 2:
    Two letter country code as per ISO 3166-1

    pos 3 & 4:
    Two check digits as per ISO 7064

    pos 5 onwards:
    Max 30 positions for the account number as per national standards.
    Can contain digits and letters.

    For the country independent part of the checks we can check if the country code is in a list of valid country codes. We can do this be programming a case statement with an elsecase for the error situation.
    It is Ok to hardcode this, the list will change but not very often and we need to program specific checks per country anyway.

    (from wikipedia) The preferred algorithm is:
    Check that the total IBAN length is correct as per the country. If not, the IBAN is invalid.
    Replace the two check digits by 00 (e.g., GB00 for the UK).
    Move the four initial characters to the end of the string.
    Replace the letters in the string with digits, expanding the string as necessary, such that A or a=10, B or b=11 and Z or z=35. Each alphabetic character is therefore replaced by 2 digits.
    Convert the string to an integer (i.e., ignore leading zeroes).
    Calculate Mod-97 of the new number.
    Subtract the remainder from 98 and, if necessary, pad with a leading 0 to make a two digit number.

    We can try to check the account number in a country specific manner for more accurate results.
    For the Netherlands we can do it like this:
    Total lenght of IBAN in The Netherlands is always 18, otherwise the IBAN is not valid.
    Pos 5,6,7,8
    Four letter bank code. Needs to exist in a list of valid bank codes. (NB: Banks can have multiple codes so you can use this for validation of IBAN's but not for generation.)
    Pos 9 to 18
    Ten digit account number. (Account numbers that used to have less than 10 digits will have zero's placed in front) If it starts with more than one zero, it is a Postbank account and no more checks are possible. If it does not, then we can do the old check. To do that take the ten digits. Multiply the first digit by 1, the second digit by 2 etc. Add the result up. When you the divide the outcome by 11 there should be no remainder.

    Pseudocode:

    selectcase vIBAN[1:2]
    ___case "NL"
    ______if ($lenght(vIBAN) <> 18)
    _________askmess "Invalid lenght for %%vIBAN[1:2]%%% IBAN"
    _________exit(-1)
    ______else
    _________vIBANCheck = "%%vIBAN[5]%%%%%vIBAN[1:2]%%%00"
    _________; etc
    _________; more next time need to get back to work
    ______endif
    ___case "XX"
    ______if ($lenght(vIBAN) <> ??)
    _________; etc
    ______endif
    ___elsecase
    ______askmess "Invalid country code in IBAN"
    ______exit(-1)
    endselectcase


    Author: Theo Neeskens (tneeskens@itblockz.nl)
  11. Hi Theo,

    thanks for your posting to get the party started.

    SInce a couple of days I am working on a implementation to be used from 8.4 up t0 9.5+.

    First we check the syntax for ithe IBAN itself and the modulo97 remainder of $concat(v_IBAN[5],v_IBAN[1:4)), which has to be always 1.

    Second level is checking the syntax of the BBAN part "per country (some 70)" which includes the length as well as digit or alphadigit A-Z0-9
    This is based on the publication of the IBAN registy which may not change too often.

    The checking is expandable, so one may want to check BBAN in more deiatil againts a list of valid bankcodes for specific countries
    just like you suggested for the netherlands.

    But this will mean more maintenance effort because we will have new banks very often.
    Perhaps we may get some sponsor for this issue to get most up-to-date information for these lists.

     

    It will take me some more days to complete the documentation, then I will post it on uniface.info

     

    SUccess, Uli


    Author: ulrich-merkel (ulrichmerkel@web.de)
  12. As for manual entry of the IBAN.

    It haven't checked it yet but it seems, that most of the banks in europe, are offering bussineses to convert there BAN into IBAN. Meaning that we could automate that proces, by replacing the BAN's by the IBAN's as deliverd by the bank. .

    It's just an idea.

    Bert Hogendoorn.


    Author: gphjk (bert.hogendoorn@compuware.com)