89 lines
3.4 KiB
Ada
89 lines
3.4 KiB
Ada
with Ada.Characters.Handling; use Ada.Characters.Handling;
|
|
with Ada.Containers.Hashed_Maps;
|
|
with Ada.Strings.Hash;
|
|
|
|
package body Iban_Code is
|
|
|
|
subtype Nation is String (1..2);
|
|
|
|
package String_Integer is new Ada.Containers.Hashed_Maps
|
|
(Nation, Integer, Ada.Strings.Hash, Equivalent_Keys => "=");
|
|
|
|
Nations : String_Integer.Map;
|
|
|
|
function Is_Legal(Iban : String) return Boolean
|
|
is
|
|
Temp : String(Iban'Range) := (others => ' ');
|
|
Count : Integer;
|
|
Ch : Character;
|
|
Num : Integer := 0;
|
|
begin
|
|
-- remove blank spaces and check characters
|
|
Count := Temp'First;
|
|
for I in Iban'Range loop
|
|
case Iban(I) is
|
|
when ' ' => null;
|
|
when 'a'..'z' =>
|
|
Temp(Count) := To_Upper(Iban(I));
|
|
Count := Count + 1;
|
|
when 'A'..'Z'|'0'..'9' =>
|
|
Temp(Count) := Iban(I);
|
|
Count := Count + 1;
|
|
when others => return False;
|
|
end case;
|
|
end loop;
|
|
-- check nation code and length
|
|
if not Nations.Contains (Temp(1..2)) or else
|
|
Nations.Element (Temp(1..2))/= Count - 1 then
|
|
return False;
|
|
end if;
|
|
-- move the 4 initial characters to the end
|
|
Temp(Temp'First..Count-1) := Temp(5..Count-1) & Temp(Temp'First..4);
|
|
-- compute remainder modulo 97
|
|
for I in Temp'First..Count-1 loop
|
|
Ch := Temp(I);
|
|
if Ch in '0'..'9' then
|
|
Num := Integer'Value(Integer'Image(Num) & Ch) mod 97;
|
|
else
|
|
Num := (Num * 100 +
|
|
(Character'Pos(Ch) - Character'Pos('A') + 10)) mod 97;
|
|
end if;
|
|
end loop;
|
|
return Num = 1;
|
|
end Is_Legal;
|
|
|
|
begin
|
|
Nations.insert("AL", 28); Nations.insert("AD", 24);
|
|
Nations.insert("AT", 20); Nations.insert("AZ", 28);
|
|
Nations.insert("BE", 16); Nations.insert("BH", 22);
|
|
Nations.insert("BA", 20); Nations.insert("BR", 29);
|
|
Nations.insert("BG", 22); Nations.insert("CR", 21);
|
|
Nations.insert("HR", 21); Nations.insert("CY", 28);
|
|
Nations.insert("CZ", 24); Nations.insert("DK", 18);
|
|
Nations.insert("DO", 28); Nations.insert("EE", 20);
|
|
Nations.insert("FO", 18); Nations.insert("FI", 18);
|
|
Nations.insert("FR", 27); Nations.insert("GE", 22);
|
|
Nations.insert("DE", 22); Nations.insert("GI", 23);
|
|
Nations.insert("GR", 27); Nations.insert("GL", 18);
|
|
Nations.insert("GT", 28); Nations.insert("HU", 28);
|
|
Nations.insert("IS", 26); Nations.insert("IE", 22);
|
|
Nations.insert("IL", 23); Nations.insert("IT", 27);
|
|
Nations.insert("KZ", 20); Nations.insert("KW", 30);
|
|
Nations.insert("LV", 21); Nations.insert("LB", 28);
|
|
Nations.insert("LI", 21); Nations.insert("LT", 20);
|
|
Nations.insert("LU", 20); Nations.insert("MK", 19);
|
|
Nations.insert("MT", 31); Nations.insert("MR", 27);
|
|
Nations.insert("MU", 30); Nations.insert("MC", 27);
|
|
Nations.insert("MD", 24); Nations.insert("ME", 22);
|
|
Nations.insert("NL", 18); Nations.insert("NO", 15);
|
|
Nations.insert("PK", 24); Nations.insert("PS", 29);
|
|
Nations.insert("PL", 28); Nations.insert("PT", 25);
|
|
Nations.insert("RO", 24); Nations.insert("SM", 27);
|
|
Nations.insert("SA", 24); Nations.insert("RS", 22);
|
|
Nations.insert("SK", 24); Nations.insert("SI", 19);
|
|
Nations.insert("ES", 24); Nations.insert("SE", 24);
|
|
Nations.insert("CH", 21); Nations.insert("TN", 24);
|
|
Nations.insert("TR", 26); Nations.insert("AE", 23);
|
|
Nations.insert("GB", 22); Nations.insert("VG", 24);
|
|
end Iban_Code;
|