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 |
parse arg @.0 /*get optional first argument from C.L.*/ |
||
do k=0+(arg()==0) while @.k\=='' /*either: 0 or |
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 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 |
/*──────────────────────────────────VALIDATEIBAN subroutine───────────────────*/ |
||
validateIBAN: procedure; arg x; numeric digits 200 /*allow for big #s*/ |
|||
x=space(x,0); L=length(x) /*elide blanks |
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 |
'RS 22 SA 24 SE 24 SI 19 SK 24 SM 27 TN 24 TR 26 VG 24' /*country list.*/ |
||
@abc# = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' /*alphabet |
@abc# = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' /*alphabet and decimal digits.*/ |
||
cc_=left(x,2); kk=substr(x,3,2) /*get IBAN country code |
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. */ |
||
cL=word(cc,c#+1) /*get the length of the country's IBAN.*/ |
|||
e= '***error!*** invalid IBAN' /*literal used when displaying an error*/ |
|||
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 |
if cL\==L then return e 'length:' L ' (should be' cL")" |
||
y=substr(x,5)left(x,4) /*put |
y=substr(x,5)left(x,4) /*put four digs in front ───► the back.*/ |
||
z= /*translate |
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 |
if z//97==1 then return 0 /*check if correct remainder (modulus).*/ |
||
return |
return e 'check digits.'</lang> |
||
'''output''' when using the default input: |
'''output''' 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 ' |
||
parse arg @.0 /*get optional first argument from C.L.*/ |
|||
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 |
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 |
/*──────────────────────────────────VALIDATEIBAN subroutine───────────────────────────────────────*/ |
||
validateIBAN: procedure; arg x; numeric digits 200 /*allow for big #s*/ |
|||
x=space(x,0); L=length(x) /*elide blanks |
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 |
'RS 22 SA 24 SE 24 SI 19 SK 24 SM 27 TN 24 TR 26 VG 24' /*country list.*/ |
||
@abc# = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' /*alphabet |
@abc# = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' /*alphabet and decimal digits.*/ |
||
cc_=left(x,2); kk=substr(x,3,2) /*get IBAN country code |
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. */ |
||
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:', |
|||
if c#==0 then return e 'country code:' cc_ |
|||
if \datatype(x,'A') then return e 'character:' substr(x,verify(x,@abc#),1) |
|||
if cL\==L then return |
if cL\==L then return e 'length:' L ' (should be' cL")" |
||
if cc_=='BR' & date("S")<20130701 then return " |
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 " |
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 |
if cc_=='BA' & kk\==39 then return e "check digits for Bosnia and Herzegovina:" kk |
||
if cc_=='MK' & kk\==07 then return |
if cc_=='MK' & kk\==07 then return e "check digits for Macedonia:" kk |
||
if cc_=='ME' & kk\==25 then return |
if cc_=='ME' & kk\==25 then return e "check digits for Montenegro:" kk |
||
if cc_=='PT' & kk\==50 then return |
if cc_=='PT' & kk\==50 then return e "check digits for Portugal:" kk |
||
if cc_=='SI' & kk\==56 then return |
if cc_=='SI' & kk\==56 then return e "check digits for Slovenia:" kk |
||
y=substr(x,5)left(x,4) /*put |
y=substr(x,5)left(x,4) /*put four digs in front ───► the back.*/ |
||
z= /*translate |
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 |
if z//97==1 then return 0 /*check if correct remainder (modulus).*/ |
||
return |
return e 'check digits.'</lang> |
||
'''output''' when using the default input, (the run date of this program is 29-April-2013): |
'''output''' when using the default input, (the run date of this program is 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> |
||