RosettaCodeData/Task/IBAN/XPL0/iban.xpl0
2024-11-04 21:53:44 -08:00

60 lines
1.8 KiB
Text

include xpllib; \for StrFind, StrLen and BigDiv
func IsValid(IBAN); \Return 'true' if IBAN is valid
char IBAN;
char CountryCodes, S(100), T(100), Addr;
int I, J, C, Len, N;
[CountryCodes:=
"AD24 AE23 AL28 AT20 AZ28 BA20 BE16 BG22 BH22 BR29
BY28 CH21 CR22 CY28 CZ24 DE22 DK18 DO28 EE20 ES24
FI18 FO18 FR27 GB22 GE22 GI23 GL18 GR27 GT28 HR21
HU28 IE22 IL23 IQ23 IS26 IT27 JO30 KW30 KZ20 LB28
LC32 LI21 LT20 LU20 LV21 MC27 MD24 ME22 MK19 MR27
MT31 MU30 NL18 NO15 PK24 PL28 PS29 PT25 QA29 RO24
RS22 SA24 SC31 SE24 SI19 SK24 SM27 ST25 SV28 TL23
TN24 TR26 UA29 VG24 XK20";
I:= 0; J:= 0; \remove spaces from IBAN
repeat C:= IBAN(I); I:= I+1;
if C # ^ then [S(J):= C; J:= J+1];
until C = 0;
for I:= 0 to 2-1 do T(I):= S(I); \check country code and length
T(2):= 0;
Addr:= StrFind(CountryCodes, T);
if Addr = 0 then return false;
Len:= StrLen(S);
N:= 10 * (Addr(2)-^0);
N:= N + (Addr(3)-^0);
if N # Len then return false;
for I:= 0 to 4-1 do \move first 4 characters to the end
[C:= S(0);
for J:= 0 to Len-2 do
S(J):= S(J+1);
S(J):= C;
];
I:= 0; J:= 0; \replace A to Z with numbers 10 thru 35
repeat C:= S(I); I:= I+1;
if C>=^A & C<=^Z then
[N:= C-^A + 10;
T(J):= N/10 + ^0; J:= J+1;
T(J):= rem(0) + ^0; J:= J+1;
]
else [T(J):= C; J:= J+1];
until C = 0;
BigDiv(T, 97); \check whether mod 97 calculation gives a remainder of 1
return rem(0) = 1;
];
int IBANs, I;
[IBANs:= ["GB82 WEST 1234 5698 7654 32", "GB82 TEST 1234 5698 7654 32"];
for I:= 0 to 2-1 do
[Text(0, IBANs(I));
Text(0, if IsValid(IBANs(I)) then " may be valid" else " is not valid");
CrLf(0);
];
]