IBAN: Difference between revisions

Content added Content deleted
m (Add missing condition in Logtalk solution.)
m (→‎{{header|REXX}}: added/changed whitespace and comments, collapsed text width for error messages,)
Line 2,500: Line 2,500:
These REXX programs can validate an IBAN specified on the command line or from an internal list.
These REXX programs can validate an IBAN specified on the command line or from an internal list.
===basic checking===
===basic checking===
<lang rexx>/*REXX program validates an IBAN (International Bank Account Number). */
<lang rexx>/*REXX program validates an IBAN (International Bank Account Number). */
@. =
@. =
@.1 = 'GB82 WEST 1234 5698 7654 32 '
@.1 = 'GB82 WEST 1234 5698 7654 32 '
Line 2,513: Line 2,513:
@.10 = 'US12 3456 7890 0987 6543 210 '
@.10 = 'US12 3456 7890 0987 6543 210 '
@.11 = 'GR16 0110 1250 0000 0001 2300 695X '
@.11 = 'GR16 0110 1250 0000 0001 2300 695X '
parse arg @.0 /*get optional first argument.*/
parse arg @.0 /*get optional first argument from C.L.*/
do k=0+(arg()==0) while @.k\=='' /*either: 0 or 1──►n*/
do k=0+(arg()==0) while @.k\=='' /*either: 0 or 1 ──► n*/
r = validateIBAN(@.k)
r = validateIBAN(@.k)
if r==0 then say ' valid IBAN:' @.k
if r==0 then say ' valid IBAN:' @.k
else say 'invalid IBAN:' @.k " " r
else say 'invalid IBAN:' @.k " " r
if k==0 then leave /*if user specified IBAN, we done*/
if k==0 then leave /*User specified IBAN? Then we're done*/
end /*k*/
end /*k*/
exit /*stick a fork in it, we're done.*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────VALIDATEIBAN subroutine───────────────────────────────*/
/*──────────────────────────────────VALIDATEIBAN subroutine───────────────────*/
valIdateIBAN: procedure; arg x; numeric digits 200 /*allow big #s*/
validateIBAN: procedure; arg x; numeric digits 200 /*allow for big #s*/
x=space(x,0); L=length(x) /*elide blanks, determine length.*/
x=space(x,0); L=length(x) /*elide blanks; determine the length.*/
cc = 'AD 24 AE 23 AL 28 AT 20 AZ 28 BA 20 BE 16 BG 22 BH 22 BR 29 CH 21',
cc = 'AD 24 AE 23 AL 28 AT 20 AZ 28 BA 20 BE 16 BG 22 BH 22 BR 29 CH 21',
'CR 21 CY 28 CZ 24 DE 22 DK 18 DO 28 EE 20 ES 24 FI 18 FO 18 FR 27',
'CR 21 CY 28 CZ 24 DE 22 DK 18 DO 28 EE 20 ES 24 FI 18 FO 18 FR 27',
Line 2,529: Line 2,529:
'IT 27 KW 30 KZ 20 LB 28 LI 21 LT 20 LU 20 LV 21 MC 27 MD 24 ME 22',
'IT 27 KW 30 KZ 20 LB 28 LI 21 LT 20 LU 20 LV 21 MC 27 MD 24 ME 22',
'MK 19 MR 27 MT 31 MU 30 NL 18 NO 15 PK 24 PL 28 PS 29 PT 25 RO 24',
'MK 19 MR 27 MT 31 MU 30 NL 18 NO 15 PK 24 PL 28 PS 29 PT 25 RO 24',
'RS 22 SA 24 SE 24 SI 19 SK 24 SM 27 TN 24 TR 26 VG 24' /*country,L*/
'RS 22 SA 24 SE 24 SI 19 SK 24 SM 27 TN 24 TR 26 VG 24' /*country list.*/
@abc# = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' /*alphabet & decimal digs*/
@abc# = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' /*alphabet and decimal digits.*/
cc_=left(x,2); kk=substr(x,3,2) /*get IBAN country code, checkDig*/
cc_=left(x,2); kk=substr(x,3,2) /*get IBAN country code and checkDigits*/
c#=wordpos(cc_,cc) /*find the country code index. */
c#=wordpos(cc_,cc) /*find the country code index. */
if c#==0 then return '***error!*** invalid country code:' cc_
cL=word(cc,c#+1) /*get the length of the country's IBAN.*/
if \datatype(x,'A') then return '***error!*** invalid character:',
e= '***error!*** invalid IBAN' /*literal used when displaying an error*/
substr(x,verify(x,@abc#),1)
if c#==0 then return e 'country code:' cc_
if \datatype(x,'A') then return e 'character:' substr(x,verify(x,@abc#),1)
cL=word(cc,c#+1) /*get length of country's IBAN. */
if cL\==L then return '***error!*** invalid IBAN length:' L ' (should be' cL")"
if cL\==L then return e 'length:' L ' (should be' cL")"
y=substr(x,5)left(x,4) /*put 4 in front ───► the back. */
y=substr(x,5)left(x,4) /*put four digs in front ───► the back.*/
z= /*translate characters──►digits. */
z= /* [↓] translate characters ──► digits*/
do j=1 for L; _=substr(y,j,1)
do j=1 for L; _=substr(y,j,1)
if datatype(_,'U') then z=z || pos(_,@abc#)+9
if datatype(_,'U') then z=z || pos(_,@abc#)+9
Line 2,545: Line 2,545:
end /*j*/
end /*j*/


if z//97==1 then return 0 /*check to see if correct modulus*/
if z//97==1 then return 0 /*check if correct remainder (modulus).*/
return '***error!*** invalid check digits.'</lang>
return e 'check digits.'</lang>
'''output''' when using the default input:
'''output''' &nbsp; when using the default input:
<pre>
<pre>
valid IBAN: GB82 WEST 1234 5698 7654 32
valid IBAN: GB82 WEST 1234 5698 7654 32
valid IBAN: Gb82 West 1234 5698 7654 32
valid IBAN: Gb82 West 1234 5698 7654 32
invalid IBAN: GB82 TEST 1234 5698 7654 32 ***error!*** invalid check digits.
invalid IBAN: GB82 TEST 1234 5698 7654 32 ***error!*** invalid check digits.
valid IBAN: GR16 0110 1250 0000 0001 2300 695
valid IBAN: GR16 0110 1250 0000 0001 2300 695
valid IBAN: GB29 NWBK 6016 1331 9268 19
valid IBAN: GB29 NWBK 6016 1331 9268 19
Line 2,557: Line 2,557:
valid IBAN: CH93 0076 2011 6238 5295 7
valid IBAN: CH93 0076 2011 6238 5295 7
valid IBAN: IL62 0108 0000 0009 9999 999
valid IBAN: IL62 0108 0000 0009 9999 999
invalid IBAN: IL62-0108-0000-0009-9999-999 ***error!*** invalid character: -
invalid IBAN: IL62-0108-0000-0009-9999-999 ***error!*** invalid IBAN character: -
invalid IBAN: US12 3456 7890 0987 6543 210 ***error!*** invalid country code: US
invalid IBAN: US12 3456 7890 0987 6543 210 ***error!*** invalid IBAN country code: US
invalid IBAN: GR16 0110 1250 0000 0001 2300 695X ***error!*** invalid IBAN length: 28 (should be 27)
invalid IBAN: GR16 0110 1250 0000 0001 2300 695X ***error!*** invalid IBAN length: 28 (should be 27)
</pre>
</pre>


Line 2,566: Line 2,566:
:* checks for two countries that may not be valid (as per their entry date into the IBAN system)
:* checks for two countries that may not be valid (as per their entry date into the IBAN system)
:* checks some countries to make sure their check digits match a specific value
:* checks some countries to make sure their check digits match a specific value
<lang rexx>/*REXX program validates an IBAN (International Bank Account Number). */
<lang rexx>/*REXX program validates an IBAN (International Bank Account Number). */
@. =
@. =
@.1 = 'GB82 WEST 1234 5698 7654 32 '
@.1 = 'GB82 WEST 1234 5698 7654 32 '
Line 2,579: Line 2,579:
@.10 = 'US12 3456 7890 0987 6543 210 '
@.10 = 'US12 3456 7890 0987 6543 210 '
@.11 = 'GR16 0110 1250 0000 0001 2300 695X '
@.11 = 'GR16 0110 1250 0000 0001 2300 695X '
@.12 = 'GT11 2222 3333 4444 5555 6666 7777 '
parse arg @.0 /*get optional first argument from C.L.*/
@.13 = 'MK11 2222 3333 4444 555 '
do k=0+(arg()==0) while @.k\=='' /*either: 0 or 1 ──► n*/
parse arg @.0 /*get optional first argument.*/
do k=0+(arg()==0) while @.k\=='' /*either: 0 or 1──►n*/
r = validateIBAN(@.k)
r = validateIBAN(@.k)
if r==0 then say ' valid IBAN:' @.k
if r==0 then say ' valid IBAN:' @.k
else say 'invalid IBAN:' @.k " " r
else say 'invalid IBAN:' @.k " " r
if k==0 then leave /*if user specified IBAN, we done*/
if k==0 then leave /*User specified IBAN? Then we're done*/
end /*k*/
end /*k*/
exit /*stick a fork in it, we're done.*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────VALIDATEIBAN subroutine───────────────────────────────────────────────────────────────*/
/*──────────────────────────────────VALIDATEIBAN subroutine───────────────────────────────────────*/
valIdateIBAN: procedure; arg x; numeric digits 200 /*allow big #s*/
validateIBAN: procedure; arg x; numeric digits 200 /*allow for big #s*/
x=space(x,0); L=length(x) /*elide blanks, determine length.*/
x=space(x,0); L=length(x) /*elide blanks; determine the length.*/
cc = 'AD 24 AE 23 AL 28 AT 20 AZ 28 BA 20 BE 16 BG 22 BH 22 BR 29 CH 21',
cc = 'AD 24 AE 23 AL 28 AT 20 AZ 28 BA 20 BE 16 BG 22 BH 22 BR 29 CH 21',
'CR 21 CY 28 CZ 24 DE 22 DK 18 DO 28 EE 20 ES 24 FI 18 FO 18 FR 27',
'CR 21 CY 28 CZ 24 DE 22 DK 18 DO 28 EE 20 ES 24 FI 18 FO 18 FR 27',
Line 2,597: Line 2,595:
'IT 27 KW 30 KZ 20 LB 28 LI 21 LT 20 LU 20 LV 21 MC 27 MD 24 ME 22',
'IT 27 KW 30 KZ 20 LB 28 LI 21 LT 20 LU 20 LV 21 MC 27 MD 24 ME 22',
'MK 19 MR 27 MT 31 MU 30 NL 18 NO 15 PK 24 PL 28 PS 29 PT 25 RO 24',
'MK 19 MR 27 MT 31 MU 30 NL 18 NO 15 PK 24 PL 28 PS 29 PT 25 RO 24',
'RS 22 SA 24 SE 24 SI 19 SK 24 SM 27 TN 24 TR 26 VG 24' /*country,L*/
'RS 22 SA 24 SE 24 SI 19 SK 24 SM 27 TN 24 TR 26 VG 24' /*country list.*/
@abc# = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' /*alphabet & decimal digs*/
@abc# = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' /*alphabet and decimal digits.*/
cc_=left(x,2); kk=substr(x,3,2) /*get IBAN country code, checkDig*/
cc_=left(x,2); kk=substr(x,3,2) /*get IBAN country code and checkDigits*/
c#=wordpos(cc_,cc) /*find the country code index. */
c#=wordpos(cc_,cc) /*find the country code index. */
if c#==0 then return '***error!*** invalid country code:' cc_
cL=word(cc,c#+1) /*get the length of the country's IBAN.*/
e= '***error!*** invalid IBAN' /*literal used when displaying an error*/
if \datatype(x,'A') then return '***error!*** invalid character:',
substr(x,verify(x,@abc#),1)
if c#==0 then return e 'country code:' cc_
cL=word(cc,c#+1) /*get length of country's IBAN. */
if \datatype(x,'A') then return e 'character:' substr(x,verify(x,@abc#),1)
if cL\==L then return '***error!*** invalid IBAN length:' L ' (should be' cL")"
if cL\==L then return e 'length:' L ' (should be' cL")"
if cc_=='BR' & date("S")<20130701 then return "***error!*** invalid IBAN country, Brazil isn't valid until 1-July-2013."
if cc_=='BR' & date("S")<20130701 then return e "country, Brazil isn't valid until 1-July-2013."
if cc_=='GT' & date("S")<20140701 then return "***error!*** invalid IBAN country, Guatemala isn't valid until 1-July-2014."
if cc_=='GT' & date("S")<20140701 then return e "country, Guatemala isn't valid until 1-July-2014."
if cc_=='BA' & kk\==39 then return "***error!*** invalid check digits for Bosnia and Herzegovina:" kk
if cc_=='BA' & kk\==39 then return e "check digits for Bosnia and Herzegovina:" kk
if cc_=='MK' & kk\==07 then return "***error!*** invalid check digits for Macedonia:" kk
if cc_=='MK' & kk\==07 then return e "check digits for Macedonia:" kk
if cc_=='ME' & kk\==25 then return "***error!*** invalid check digits for Montenegro:" kk
if cc_=='ME' & kk\==25 then return e "check digits for Montenegro:" kk
if cc_=='PT' & kk\==50 then return "***error!*** invalid check digits for Portugal:" kk
if cc_=='PT' & kk\==50 then return e "check digits for Portugal:" kk
if cc_=='SI' & kk\==56 then return "***error!*** invalid check digits for Slovenia:" kk
if cc_=='SI' & kk\==56 then return e "check digits for Slovenia:" kk
y=substr(x,5)left(x,4) /*put 4 in front ───► the back. */
y=substr(x,5)left(x,4) /*put four digs in front ───► the back.*/
z= /*translate characters──►digits. */
z= /* [↓] translate characters ──► digits*/
do j=1 for L; _=substr(y,j,1)
do j=1 for L; _=substr(y,j,1)
if datatype(_,'U') then z=z || pos(_,@abc#)+9
if datatype(_,'U') then z=z || pos(_,@abc#)+9
Line 2,620: Line 2,618:
end /*j*/
end /*j*/


if z//97==1 then return 0 /*check to see if correct modulus*/
if z//97==1 then return 0 /*check if correct remainder (modulus).*/
return '***error!*** invalid check digits.'</lang>
return e 'check digits.'</lang>
'''output''' when using the default input, &nbsp; (the run date of this program is &nbsp; 29-April-2013):
'''output''' &nbsp; when using the default input, &nbsp; (the run date of this program is &nbsp; 29-April-2013):
<pre>
<pre>
valid IBAN: GB82 WEST 1234 5698 7654 32
valid IBAN: GB82 WEST 1234 5698 7654 32
valid IBAN: Gb82 West 1234 5698 7654 32
valid IBAN: Gb82 West 1234 5698 7654 32
invalid IBAN: GB82 TEST 1234 5698 7654 32 ***error!*** invalid check digits.
invalid IBAN: GB82 TEST 1234 5698 7654 32 ***error!*** invalid IBAN check digits.
valid IBAN: GR16 0110 1250 0000 0001 2300 695
valid IBAN: GR16 0110 1250 0000 0001 2300 695
valid IBAN: GB29 NWBK 6016 1331 9268 19
valid IBAN: GB29 NWBK 6016 1331 9268 19
Line 2,632: Line 2,630:
valid IBAN: CH93 0076 2011 6238 5295 7
valid IBAN: CH93 0076 2011 6238 5295 7
valid IBAN: IL62 0108 0000 0009 9999 999
valid IBAN: IL62 0108 0000 0009 9999 999
invalid IBAN: IL62-0108-0000-0009-9999-999 ***error!*** invalid character: -
invalid IBAN: IL62-0108-0000-0009-9999-999 ***error!*** invalid IBAN character: -
invalid IBAN: US12 3456 7890 0987 6543 210 ***error!*** invalid country code: US
invalid IBAN: US12 3456 7890 0987 6543 210 ***error!*** invalid IBAN country code: US
invalid IBAN: GR16 0110 1250 0000 0001 2300 695X ***error!*** invalid IBAN length: 28 (should be 27)
invalid IBAN: GR16 0110 1250 0000 0001 2300 695X ***error!*** invalid IBAN length: 28 (should be 27)
invalid IBAN: GT11 2222 3333 4444 5555 6666 7777 ***error!*** invalid IBAN country, Guatemala isn't valid until 1-July-2014.
invalid IBAN: GT11 2222 3333 4444 5555 6666 7777 ***error!*** invalid IBAN country, Guatemala isn't valid until 1-July-2014.
invalid IBAN: MK11 2222 3333 4444 555 ***error!*** invalid check digits for Macedonia: 11
invalid IBAN: MK11 2222 3333 4444 555 ***error!*** invalid IBAN check digits for Macedonia: 11
</pre>
</pre>