Data update

This commit is contained in:
Ingy döt Net 2025-02-27 18:35:13 -05:00
parent 8e4e15fa56
commit 72eb4943cb
1853 changed files with 35514 additions and 9441 deletions

104
Task/IBAN/ALGOL-68/iban.alg Normal file
View file

@ -0,0 +1,104 @@
BEGIN # validate IBAN numbers #
# country code and expected bank account length for IBAN codes #
MODE IBANCOUNTRY = STRUCT( [ 1 : 2 ]CHAR code, INT length );
[]IBANCOUNTRY country info =
( ("AL",28), ("AD",24), ("AT",20), ("AZ",28), ("BE",16), ("BH",22), ("BA",20), ("BR",29)
, ("BG",22), ("CR",21), ("HR",21), ("CY",28), ("CZ",24), ("DK",18), ("DO",28), ("EE",20)
, ("FO",18), ("FI",18), ("FR",27), ("GE",22), ("DE",22), ("GI",23), ("GR",27), ("GL",18)
, ("GT",28), ("HU",28), ("IS",26), ("IE",22), ("IL",23), ("IT",27), ("KZ",20), ("KW",30)
, ("LV",21), ("LB",28), ("LI",21), ("LT",20), ("LU",20), ("MK",19), ("MT",31), ("MR",27)
, ("MU",30), ("MC",27), ("MD",24), ("ME",22), ("NL",18), ("NO",15), ("PK",24), ("PS",29)
, ("PL",28), ("PT",25), ("RO",24), ("SM",27), ("SA",24), ("RS",22), ("SK",24), ("SI",19)
, ("ES",24), ("SE",24), ("CH",21), ("TN",24), ("TR",26), ("AE",23), ("GB",22), ("VG",24)
);
# returns "" if s could be a valid IBAN, an error message otherwise #
OP POSSIBLEIBAN = ( STRING s )STRING:
BEGIN
BOOL is valid := TRUE;
STRING result := "";
# remove spaces and check we only have digits and spaces #
STRING iban := "";
FOR s pos FROM LWB s TO UPB s WHILE is valid DO
CHAR c = s[ s pos ];
IF c /= " " THEN
IF NOT ( is valid := ( c >= "A" AND c <= "Z" ) OR ( c >= "0" AND c <= "9" ) )
THEN result := "Invalid character: " + c
FI;
iban +:= c
FI
OD;
IF is valid THEN
# OK so far - check the length matches the country code #
INT supplied length = ( UPB iban - LWB iban ) + 1;
is valid := FALSE;
IF supplied length <= 4
THEN result := "Code is too short"
ELSE # enough characters for a country code and a check sum #
INT expected length := -1;
STRING supplied country = iban[ LWB iban : LWB iban + 1 ];
FOR c pos FROM LWB country info TO UPB country info WHILE NOT is valid DO
IF is valid := code OF country info[ c pos ] = supplied country THEN
expected length := length OF country info[ c pos ]
FI
OD;
IF NOT is valid
THEN result := "Not a known IBAN country: " + supplied country
ELIF NOT ( is valid := expected length = supplied length )
THEN result := "Expected code length: " + whole( expected length, 0 )
+ " but actual length is: " + whole( supplied length, 0 )
ELSE # OK so far - check the checksum #
STRING rearranged iban = iban[ LWB iban + 4 : ] + iban[ LWB iban : LWB iban + 3 ];
LONG LONG INT numeric iban := 0;
FOR c pos FROM LWB rearranged iban TO UPB rearranged iban DO
CHAR c = rearranged iban[ c pos ];
IF c >= "0" AND c <= "9" THEN
numeric iban *:= 10 +:= ( ABS c - ABS "0" )
ELSE
numeric iban *:= 100 +:= ( ABS c - ABS "A" ) + 10
FI
OD;
IF NOT ( is valid := numeric iban MOD 97 = 1 )
THEN result := "Incorrect checksum"
FI
FI
FI
FI;
IF is valid THEN "" ELIF result = "" THEN "Unknown error" ELSE result FI
END # POSSIBLEIBAN # ;
BEGIN # tests #
[]STRING valid codes = ( "GB82 WEST 1234 5698 7654 32", "GB82WEST12345698765432"
, "GR16 0110 1250 0000 0001 2300 695", "GB29 NWBK 6016 1331 9268 19"
, "SA03 8000 0000 6080 1016 7519", "CH93 0076 2011 6238 5295 7"
, "IL62 0108 0000 0009 9999 999"
);
[]STRING invalid codes = ( "gb82 west 1234 5698 7654 32" # invalid characters #
, "GB82 TEST 1234 5698 7654 32" # invalid check digits #
, "IL62-0108-0000-0009-9999-999" # invalid characters #
, "US12 3456 7890 0987 6543 210" # invalid country code #
, "GR16 0110 1250 0000 0001 2300 695X" # invalid code length #
, "" # code is too short #
, "G2" # code is too short #
, "GB271" # invalid code length #
);
FOR t pos FROM LWB valid codes TO UPB valid codes DO
STRING code = valid codes[ t pos ];
STRING message = POSSIBLEIBAN code;
IF message = ""
THEN print( ( "Possible IBAN: ", code, newline ) )
ELSE print( ( "INVALID IBAN: ", code, ": UNEXPECTED ERROR: ", message, newline ) )
FI
OD;
FOR t pos FROM LWB invalid codes TO UPB invalid codes DO
STRING code = invalid codes[ t pos ];
STRING message = POSSIBLEIBAN code;
IF message = ""
THEN print( ( "POSSIBLE IBAN: ", code, " BUT EXPECTED AN ERROR MESSAGE", newline ) )
ELSE print( ( "Invalid IBAN: ", code, ": ", message, newline ) )
FI
OD
END
END

View file

@ -0,0 +1,33 @@
var
countryLen := Dict(
('AL', 28), ('AD', 24), ('AT', 20), ('AZ', 28), ('BE', 16), ('BH', 22), ('BA', 20), ('BR', 29),
('BG', 22), ('CR', 21), ('HR', 21), ('CY', 28), ('CZ', 24), ('DK', 18), ('DO', 28), ('EE', 20),
('FO', 18), ('FI', 18), ('FR', 27), ('GE', 22), ('DE', 22), ('GI', 23), ('GR', 27), ('GL', 18),
('GT', 28), ('HU', 28), ('IS', 26), ('IE', 22), ('IL', 23), ('IT', 27), ('KZ', 20), ('KW', 30),
('LV', 21), ('LB', 28), ('LI', 21), ('LT', 20), ('LU', 20), ('MK', 19), ('MT', 31), ('MR', 27),
('MU', 30), ('MC', 27), ('MD', 24), ('ME', 22), ('NL', 18), ('NO', 15), ('PK', 24), ('PS', 29),
('PL', 28), ('PT', 25), ('RO', 24), ('SM', 27), ('SA', 24), ('RS', 22), ('SK', 24), ('SI', 19),
('ES', 24), ('SE', 24), ('CH', 21), ('TN', 24), ('TR', 26), ('AE', 23), ('GB', 22), ('VG', 24));
function validIban(iban: string): boolean;
begin
result := False;
iban := iban.Replace(' ', '').Replace(#9, '');
if not iban.All(c -> c.isupper or c.isdigit) then exit;
if iban.Length <> countryLen.Get(iban[1:3]) then exit;
iban := iban[5:iban.Length + 1] + iban[1:5];
var digits: string := '';
foreach var ch in iban do
case ch of
'0'..'9': digits += ch;
'A'..'Z': digits += (Ord(ch) - Ord('A') + 10).ToString;
end;
result := digits.ToBigInteger mod 97 = 1;
end;
begin
foreach var account in |'GB82 WEST 1234 5698 7654 32', 'GB82 TEST 1234 5698 7654 32'| do
Println(account, 'validation is:', validIban(account));
end.