RosettaCodeData/Task/IBAN/Oberon/iban.oberon
2023-07-01 13:44:08 -04:00

161 lines
4.6 KiB
Text

MODULE IBAN;
IMPORT
Out,
Err,
ADT:Dictionary,
Object:Boxed,
Object:BigInt,
Object,
Strings,
IntStr;
TYPE
IBANLen = Boxed.LongInt;
VAR
nations: Dictionary.Dictionary(STRING,IBANLen);
PROCEDURE Check*(iban: ARRAY OF CHAR): BOOLEAN;
VAR
country,ibanStr: Object.String;
nLetter: ARRAY 3 OF CHAR;
block: ARRAY 5 OF CHAR;
numIban: ARRAY 256 OF CHAR;
num,den,res: BigInt.BigInt;
ibanLen: IBANLen;
i: LONGINT;
BEGIN
ibanStr := Object.NewLatin1(iban);
country := ibanStr.Substring(0,2);
IF ~nations.HasKey(country) THEN
Err.Object("Country " + country + " has not IBAN codes. ");
RETURN FALSE;
END;
ibanLen := nations.Get(country);
IF SHORT(ibanLen.value) # Strings.Length(iban) THEN
Err.Object("IBAN length incorrect for " + country +". ");
RETURN FALSE
END;
block[0] := 0X;
Strings.Extract(iban,0,4,block);
Strings.Delete(iban,0,4);Strings.Append(block,iban);
numIban[0] := 0X;
FOR i := 0 TO LEN(iban) - 1 DO
nLetter[0] := 0X;
IF (iban[i] >= 'A') & (iban[i] <= 'Z') THEN
IntStr.IntToStr(ORD(iban[i]) - ORD('A') + 10,nLetter);
ELSE
nLetter[0] := iban[i];
nLetter[1] := 0X
END;
Strings.Append(nLetter,numIban);
END;
Strings.Append(0X,numIban);
num := BigInt.New(Object.NewLatin1(numIban),10);
den := BigInt.New("97",10);
res := num.Mod(den);
IF res.Equals(BigInt.one) THEN
RETURN TRUE
ELSE
Err.String("IBAN code check failed. ");
RETURN FALSE
END
END Check;
PROCEDURE CodeLengthFor*(country: ARRAY OF CHAR): LONGINT;
VAR
countryStr: Object.String;
ibanLen: IBANLen;
BEGIN
countryStr := Object.NewLatin1(country);
ibanLen := Boxed.zeroLongInt;
IF nations.HasKey(countryStr) THEN
ibanLen := nations.Get(countryStr)
END;
RETURN ibanLen.value
END CodeLengthFor;
PROCEDURE Test*;
PROCEDURE DoCheck(iban: ARRAY OF CHAR);
BEGIN
Out.String("IBAN[");Out.String(iban);Out.String("]=");Out.Bool(Check(iban));
Out.Ln
END DoCheck;
BEGIN
DoCheck("CH9300762011623852957");
DoCheck("GB82WEST12345698765432");
DoCheck("SA0380000000608010167519");
DoCheck("XX0380000000608010167519");
END Test;
BEGIN
nations := NEW(Dictionary.Dictionary(STRING,Boxed.LongInt));
nations.Set("AL",NEW(IBANLen,28));
nations.Set("AD",NEW(IBANLen,24));
nations.Set("AT",NEW(IBANLen,20));
nations.Set("AZ",NEW(IBANLen,28));
nations.Set("BE",NEW(IBANLen,16));
nations.Set("BH",NEW(IBANLen,22));
nations.Set("BA",NEW(IBANLen,20));
nations.Set("BR",NEW(IBANLen,29));
nations.Set("BG",NEW(IBANLen,22));
nations.Set("CR",NEW(IBANLen,21));
nations.Set("HR",NEW(IBANLen,21));
nations.Set("CY",NEW(IBANLen,28));
nations.Set("CZ",NEW(IBANLen,24));
nations.Set("DK",NEW(IBANLen,18));
nations.Set("DO",NEW(IBANLen,28));
nations.Set("EE",NEW(IBANLen,20));
nations.Set("FO",NEW(IBANLen,18));
nations.Set("FI",NEW(IBANLen,18));
nations.Set("FR",NEW(IBANLen,27));
nations.Set("GE",NEW(IBANLen,22));
nations.Set("DE",NEW(IBANLen,22));
nations.Set("GI",NEW(IBANLen,23));
nations.Set("GR",NEW(IBANLen,27));
nations.Set("GL",NEW(IBANLen,18));
nations.Set("GT",NEW(IBANLen,28));
nations.Set("HU",NEW(IBANLen,28));
nations.Set("IS",NEW(IBANLen,26));
nations.Set("IE",NEW(IBANLen,22));
nations.Set("IL",NEW(IBANLen,23));
nations.Set("IT",NEW(IBANLen,27));
nations.Set("KZ",NEW(IBANLen,20));
nations.Set("KW",NEW(IBANLen,30));
nations.Set("LV",NEW(IBANLen,21));
nations.Set("LB",NEW(IBANLen,28));
nations.Set("LI",NEW(IBANLen,21));
nations.Set("LT",NEW(IBANLen,20));
nations.Set("LU",NEW(IBANLen,20));
nations.Set("MK",NEW(IBANLen,19));
nations.Set("MT",NEW(IBANLen,31));
nations.Set("MR",NEW(IBANLen,27));
nations.Set("MU",NEW(IBANLen,30));
nations.Set("MC",NEW(IBANLen,27));
nations.Set("MD",NEW(IBANLen,24));
nations.Set("ME",NEW(IBANLen,22));
nations.Set("NL",NEW(IBANLen,18));
nations.Set("NO",NEW(IBANLen,15));
nations.Set("PK",NEW(IBANLen,24));
nations.Set("PS",NEW(IBANLen,29));
nations.Set("PL",NEW(IBANLen,28));
nations.Set("PT",NEW(IBANLen,25));
nations.Set("RO",NEW(IBANLen,24));
nations.Set("SM",NEW(IBANLen,27));
nations.Set("SA",NEW(IBANLen,24));
nations.Set("RS",NEW(IBANLen,22));
nations.Set("SK",NEW(IBANLen,24));
nations.Set("SI",NEW(IBANLen,19));
nations.Set("ES",NEW(IBANLen,24));
nations.Set("SE",NEW(IBANLen,24));
nations.Set("CH",NEW(IBANLen,21));
nations.Set("TN",NEW(IBANLen,24));
nations.Set("TR",NEW(IBANLen,26));
nations.Set("AE",NEW(IBANLen,23));
nations.Set("GB",NEW(IBANLen,22));
nations.Set("VG",NEW(IBANLen,24));
Test;
END IBAN.