Just make sure the IBAN is all upper case to begin with to eliminate a lot of coding. SET VAR vIBAN = (LUC((.vIBAN))
Dennis McGrath Software Developer QMI Security Solutions 1661 Glenlake Ave Itasca IL 60143 630-980-8461 [email protected] From: [email protected] [mailto:[email protected]] On Behalf Of James Bentley Sent: Friday, May 03, 2013 9:05 AM To: RBASE-L Mailing List Subject: [RBASE-L] - Re: European IBAN (International Bank Account Number)check digit calculation Tony, In you code you have to account for the input method. You assume upper case "A" ASCII value 65, user could input lower case "a" ASCII value 97 and invalidate your coding. You could use the following code SET VARIABLE V_CHAR='A' or SET VARIABLE V_CHAR='a' SET VARIABLE vslocp1 =(-1 + (SLOCP('0123456789abcdefghijklmnopqrstuvwxyz','A',1))) you get an integer 10 or you could modify your function set var V1 = ((ICHAR((LUC(.V_CHAR)))) - 55) but in your example you would need to test if variable V_CHAR does not contain char '0123456789' as the ICHAR functions fails. In my example that is taken care of by the SLOCP function. Jim Bentley, American Celiac Society 1-504-737-3293 ________________________________ From: Tony IJntema <[email protected]<mailto:[email protected]>> To: RBASE-L Mailing List <[email protected]<mailto:[email protected]>> Sent: Thursday, May 2, 2013 2:22 PM Subject: [RBASE-L] - Re: European IBAN (International Bank Account Number)check digit calculation Hartmut, It's a remarkable piece of programming what you have done, It will take a little while for me to understand it completely. Without understanding in detail your solution maybe you can avoid a lot of IF statements by taking the ASCII value of each character into account. Look for ASCII in the help of Rbase. For instance the ASCII value of the capital A = 65, B = 66 and so on. What you could do is using the function ICHAR to find the ASCII value and subtract 55 from this value. It looks like this: set var V1 = ((ICHAR(.V_CHAR)) - 55) Thank you for your help. Tony -----Original Message----- From: [email protected]<mailto:[email protected]> [mailto:[email protected]<mailto:[email protected]>] On Behalf Of Dr. Hartmut Braun Sent: donderdag 2 mei 2013 20:36 To: RBASE-L Mailing List Subject: [RBASE-L] - Re: European IBAN (International Bank Account Number)check digit calculation Tony et al., I use a calculation method in 3 steps. The method avoids big INTEGER values. It is valid for Germany, Switzerland and Austria. $COMMAND vviban1 *( -------------------------------------------------------- IBAN Berechnung Einzelmitglieder International Bank Account Number aufgerufen in mi_vvrba/Daten/IBAN Bearbeiten/Ja Copyright (c) 1987-2013 Dr. Hartmut Braun, Karlsruhe Version: 12.3 R:BASE Version 7.6+9.5 32/64 -------------------------------------------------------- ) -- vvnat=nationality, vvlang=language, blz=bank code, kto=account -- midat=TABLE membership data IF vvnat <> 'd' AND vvnat <> 'z' AND vvnat <> 'o' THEN SET VAR vcapt = 'IBAN Calculator' SET VAR vmess = 'This IBAN Calculation is not available for your country!' PAUSE 1 USING .vmess + CAPTION .vcapt ICON stop + &vpausopt |THEMENAME &vtheme GOTO liban1 ENDIF SET VAR vpnr INTE = 0, vcnt INTE = 0 SET VAR vk2 INTE = 0, vk3 TEXT = NULL, vk31 TEXT = NULL SET VAR vk4 INTE = 0, vk5 TEXT = NULL SET VAR vba1 TEXT = NULL, vba2 TEXT = NULL, vba3 TEXT = NULL SET VAR vm1 INTE = 0, vm2 INTE = 0, vm3 INTE = 0, vm4 INTE = 0 SET VAR vbb1 INTE = 0, vbb2 INTE = 0, vbb3 INTE = 0, vbb4 INTE = 0 SET VAR vpz INTE = 0, vpz1 TEXT = NULL, vbban TEXT = NULL SET VAR vbban1 TEXT = NULL, vbban2 TEXT = NULL, vbban3 TEXT = NULL SELECT COUNT(*) INTO vcnt INDICATOR vi1 FROM midat + WHERE inr = '1' AND blz <> '00000000' AND blz <> '11111111' + AND iban IS NULL IF vcnt = 0 THEN GOTO liban1 ENDIF SET VAR vmess = 'Moment, ich berechne die fehlenden IBANs!' IF vvlang <> 'd' THEN SET VAR vmess = lmsg IN tstlmess + WHERE svlang = (.vvlang) AND msgnr = 194 ENDIF PAUSE 3 USING .vmess + CAPTION .vcapt ICON APP + &vpaus1opt |THEMENAME &vtheme SET ERROR MESSAGE 705 OFF DROP CURSOR ccsh1 SET ERROR MESSAGE 705 ON -- IBAN Berechnung DECLARE ccsh1 CURSOR FOR SELECT blz, kto FROM midat + WHERE inr = '1' AND blz <> '00000000' AND blz <> '11111111' + AND iban IS NULL -- DE IF vvnat = 'd' THEN OPEN ccsh1 FETCH ccsh1 INTO vblz vi1, vkto vi2 WHILE SQLCODE = 0 THEN SET VAR vk2 = (10 - (SLEN(.vkto))) SET VAR vk3 = ((SFIL('0',.vk2)) + .vkto) SET VAR vk4 = (8 - (SLEN(.vblz))) SET VAR vk5 = ((SFIL('0',.vk4)) + .vblz) SET VAR vbban = (.vk5 + .vk3) SET VAR vbban1 = (SGET(.vbban,9,1)) SET VAR vbban2 = (SGET(.vbban,7,10)) SET VAR vbban3 = ((SGET(.vbban,2,17)) + '13140') -- D = 13, E = 14 -- 1. 9er Zeile SET VAR vbb1 = (INT(.vbban1)) SET VAR vm1 = (MOD(.vbb1,97)) SET VAR vba1 = ((CTXT(.vm1)) + .vbban2) -- 2. 9er Zeile SET VAR vbb2 = (INT(.vba1)) SET VAR vm2 = (MOD(.vbb2,97)) SET VAR vba2 = ((CTXT(.vm2)) + .vbban3) -- 3. 9er Zeile SET VAR vbb3 = (INT(.vba2)) SET VAR vm3 = (MOD(.vbb3,97)) SET VAR vba3 = ((CTXT(.vm3)) + '0') -- Rest SET VAR vbb4 = (INT(.vba3)) SET VAR vm4 = (MOD(.vbb4,97)) SET VAR vpz = (98 - .vm4) IF vpz < 10 THEN SET VAR vpz1 = ('0' + (CTXT(.vpz))) ELSE SET VAR vpz1 = (CTXT(.vpz)) ENDIF UPDATE midat SET iban = ('DE' + .vpz1 + .vk5 + .vk3) + WHERE CURRENT OF ccsh1 SET VAR vpnr = (.vpnr + 1) SET VAR vdial = ((CTXT(.vpnr)) & 'von' & (CTXT(.vcnt))) PAUSE 4 USING .vdial + CAPTION 'IBAN' ICON APP + &vpausopt |THEMENAME &vtheme FETCH ccsh1 INTO vblz vi1, vkto vi2 ENDWHILE ENDIF -- CH IF vvnat = 'z' THEN OPEN ccsh1 FETCH ccsh1 INTO vblz vi1, vkto vi2 WHILE SQLCODE = 0 THEN SET VAR vk2 = (12 - (SLEN(.vkto))) SET VAR vk3 = ((SFIL('0',.vk2)) + .vkto) SET VAR vk31 = .vk3 SET VAR vk4 = (5 - (SLEN(.vblz))) SET VAR vk5 = ((SFIL('0',.vk4)) + .vblz) -- Ersetzen der Buchstaben IF vk3 CONTAINS 'A' THEN SET VAR vk31 = (SRPL(.vk31,'A','10',0)) ENDIF IF vk3 CONTAINS 'B' THEN SET VAR vk31 = (SRPL(.vk31,'B','11',0)) ENDIF IF vk3 CONTAINS 'C' THEN SET VAR vk31 = (SRPL(.vk31,'C','12',0)) ENDIF IF vk3 CONTAINS 'D' THEN SET VAR vk31 = (SRPL(.vk31,'D','13',0)) ENDIF IF vk3 CONTAINS 'E' THEN SET VAR vk31 = (SRPL(.vk31,'E','14',0)) ENDIF IF vk3 CONTAINS 'F' THEN SET VAR vk31 = (SRPL(.vk31,'F','15',0)) ENDIF IF vk3 CONTAINS 'G' THEN SET VAR vk31 = (SRPL(.vk31,'G','16',0)) ENDIF IF vk3 CONTAINS 'H' THEN SET VAR vk31 = (SRPL(.vk31,'H','17',0)) ENDIF IF vk3 CONTAINS 'I' THEN SET VAR vk31 = (SRPL(.vk31,'I','18',0)) ENDIF IF vk3 CONTAINS 'J' THEN SET VAR vk31 = (SRPL(.vk31,'J','19',0)) ENDIF IF vk3 CONTAINS 'K' THEN SET VAR vk31 = (SRPL(.vk31,'K','20',0)) ENDIF IF vk3 CONTAINS 'L' THEN SET VAR vk31 = (SRPL(.vk31,'L','21',0)) ENDIF IF vk3 CONTAINS 'M' THEN SET VAR vk31 = (SRPL(.vk31,'M','22',0)) ENDIF IF vk3 CONTAINS 'N' THEN SET VAR vk31 = (SRPL(.vk31,'N','23',0)) ENDIF IF vk3 CONTAINS 'O' THEN SET VAR vk31 = (SRPL(.vk31,'O','24',0)) ENDIF IF vk3 CONTAINS 'P' THEN SET VAR vk31 = (SRPL(.vk31,'P','25',0)) ENDIF IF vk3 CONTAINS 'Q' THEN SET VAR vk31 = (SRPL(.vk31,'Q','26',0)) ENDIF IF vk3 CONTAINS 'R' THEN SET VAR vk31 = (SRPL(.vk31,'R','27',0)) ENDIF IF vk3 CONTAINS 'S' THEN SET VAR vk31 = (SRPL(.vk31,'S','28',0)) ENDIF IF vk3 CONTAINS 'T' THEN SET VAR vk31 = (SRPL(.vk31,'T','29',0)) ENDIF IF vk3 CONTAINS 'U' THEN SET VAR vk31 = (SRPL(.vk31,'U','30',0)) ENDIF IF vk3 CONTAINS 'V' THEN SET VAR vk31 = (SRPL(.vk31,'V','31',0)) ENDIF IF vk3 CONTAINS 'W' THEN SET VAR vk31 = (SRPL(.vk31,'W','32',0)) ENDIF IF vk3 CONTAINS 'X' THEN SET VAR vk31 = (SRPL(.vk31,'X','33',0)) ENDIF IF vk3 CONTAINS 'Y' THEN SET VAR vk31 = (SRPL(.vk31,'Y','34',0)) ENDIF IF vk3 CONTAINS 'Z' THEN SET VAR vk31 = (SRPL(.vk31,'Z','35',0)) ENDIF SET VAR vbban = (.vk5 + .vk31) SET VAR vbban1 = (SGET(.vbban,9,1)) SET VAR vbban2 = (SGET(.vbban,7,10)) SET VAR vbban3 = ((SGET(.vbban,2,17)) + '12170') -- C = 12, H = 17 -- 1. 9er Zeile SET VAR vbb1 = (INT(.vbban1)) SET VAR vm1 = (MOD(.vbb1,97)) SET VAR vba1 = ((CTXT(.vm1)) + .vbban2) -- 2. 9er Zeile SET VAR vbb2 = (INT(.vba1)) SET VAR vm2 = (MOD(.vbb2,97)) SET VAR vba2 = ((CTXT(.vm2)) + .vbban3) -- 3. 9er Zeile SET VAR vbb3 = (INT(.vba2)) SET VAR vm3 = (MOD(.vbb3,97)) SET VAR vba3 = ((CTXT(.vm3)) + '0') -- Rest SET VAR vbb4 = (INT(.vba3)) SET VAR vm4 = (MOD(.vbb4,97)) SET VAR vpz = (98 - .vm4) IF vpz < 10 THEN SET VAR vpz1 = ('0' + (CTXT(.vpz))) ELSE SET VAR vpz1 = (CTXT(.vpz)) ENDIF UPDATE midat SET iban = ('CH' + .vpz1 + .vk5 + .vk3) + WHERE CURRENT OF ccsh1 SET VAR vpnr = (.vpnr + 1) SET VAR vdial = ((CTXT(.vpnr)) & 'von' & (CTXT(.vcnt))) PAUSE 4 USING .vdial + CAPTION 'IBAN' ICON APP + &vpausopt |THEMENAME &vtheme FETCH ccsh1 INTO vblz vi1, vkto vi2 ENDWHILE ENDIF -- AT IF vvnat = 'o' THEN OPEN ccsh1 FETCH ccsh1 INTO vblz vi1, vkto vi2 WHILE SQLCODE = 0 THEN SET VAR vk2 = (11 - (SLEN(.vkto))) SET VAR vk3 = ((SFIL('0',.vk2)) + .vkto) SET VAR vk4 = (5 - (SLEN(.vblz))) SET VAR vk5 = ((SFIL('0',.vk4)) + .vblz) SET VAR vbban = (.vk5 + .vk3) SET VAR vbban1 = (SGET(.vbban,9,1)) SET VAR vbban2 = (SGET(.vbban,7,10)) SET VAR vbban3 = ((SGET(.vbban,2,17)) + '10290') -- A = 10, T = 29 -- 1. 9er Zeile SET VAR vbb1 = (INT(.vbban1)) SET VAR vm1 = (MOD(.vbb1,97)) SET VAR vba1 = ((CTXT(.vm1)) + .vbban2) -- 2. 9er Zeile SET VAR vbb2 = (INT(.vba1)) SET VAR vm2 = (MOD(.vbb2,97)) SET VAR vba2 = ((CTXT(.vm2)) + .vbban3) -- 3. 9er Zeile SET VAR vbb3 = (INT(.vba2)) SET VAR vm3 = (MOD(.vbb3,97)) SET VAR vba3 = ((CTXT(.vm3)) + '0') -- Rest SET VAR vbb4 = (INT(.vba3)) SET VAR vm4 = (MOD(.vbb4,97)) SET VAR vpz = (98 - .vm4) IF vpz < 10 THEN SET VAR vpz1 = ('0' + (CTXT(.vpz))) ELSE SET VAR vpz1 = (CTXT(.vpz)) ENDIF UPDATE midat SET iban = ('AT' + .vpz1 + .vk5 + .vk3) + WHERE CURRENT OF ccsh1 SET VAR vpnr = (.vpnr + 1) SET VAR vdial = ((CTXT(.vpnr)) & 'von' & (CTXT(.vcnt))) PAUSE 4 USING .vdial + CAPTION 'IBAN' ICON APP + &vpausopt |THEMENAME &vtheme FETCH ccsh1 INTO vblz vi1, vkto vi2 ENDWHILE ENDIF DROP CURSOR ccsh1 LABEL liban1 CLS CLEAR VAR vpnr, vcnt, vk2, vk3, vk4, vk5, vk31 CLEAR VAR vba1, vba2, vba3, vm1, vm2, vm3, vm4 CLEAR VAR vbb1, vbb2, vbb3, vbb4, vpz, vpz1 CLEAR VAR vbban, vbban1, vbban2, vbban3, vi% RETURN Hartmut Braun Am 02.05.2013 09:20, schrieb Tony IJntema: > Hi, > > In 2014 we will have to use a new bank account number in Europe. > > It looks like this: NL91ABNA0417164300 > > 91 is a check digit > > This check digit is a result of a mod 97 operation. > > The calculation that needs to be performed is: > > (mod(101123100417164300232100,97)) > > (The length of the figure is 24 characters) > > The result = 7 > > The check digit then becomes 98 - 7 = 91 > > My question is: This figure is too big for a modular operation and > bignums are not allowed in the mod function. Does anybody know a workaround? > > > N.B. > > To rules to create the long figure are: > > Change the IBAN to: ABNA0417164300NL00 (Put NL (=countrycode) after > the figure and add two zeroes to it. > Replace all letters by it's position in the Alphabet and add 9 to this > number ( A = 10, B = 11, and so on) > > Tony > > >

