60 lines
1.8 KiB
Text
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);
|
|
];
|
|
]
|