IBAN: Difference between revisions

Content added Content deleted
m (added whitespace to the task's preamble, added a ;Task: (bold) section header.)
(Implementation in Standard ML)
Line 3,640: Line 3,640:
Invalid IBAN: IL62-0108-0000-0009-9999-999: length: 28 not 23
Invalid IBAN: IL62-0108-0000-0009-9999-999: length: 28 not 23
Invalid IBAN: GR16 0110 1250 0000 0001 2300 695X: length: 28 not 27</pre>
Invalid IBAN: GR16 0110 1250 0000 0001 2300 695X: length: 28 not 27</pre>



=={{header|Standard ML}}==
{{works with|SML/NJ}}

<lang sml>(* country_code : string -> int *)
(* Get the length of a valid IBAN given the two chars long country code *)
fun country_code (str : string) : int =
case str of
"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
| _ => raise Domain


(* removespace : string -> string *)
(* Removes all spaces from a string *)
fun removespace s = String.translate (fn #" " => "" | c => str c) s

(* to_upper : string -> string *)
(* Convert every char to upper of a string *)
fun to_upper (s : string) : string =
String.translate (fn c => str (Char.toUpper c)) s

(* convert_to_number : char -> string *)
(* Covert a alphanumeric char into a numerical string *)
fun convert_to_number (c : char) : string =
if Char.isDigit c then str c else
if Char.isUpper c then Int.toString (10 + ord c - ord #"A") else
raise Domain


(* verify_iban : string -> bool *)
(* Check weather a string is a valid IBAN *)
fun verify_iban str =
let
(* Remove spaces and make upper case *)
val str = to_upper (removespace str)
(* Fetch first two chars (country code) *)
val country = String.substring (str, 0, 2)
val len = country_code country
in
(* size test *)
String.size str = len
andalso
(* Every char must be alphanumeric *)
List.all Char.isAlphaNum (explode str)
andalso
let
(* Reorder *)
val str = String.substring (str, 4, String.size str - 4) ^ String.substring (str, 0, 4)
(* Convert into digits *)
val str = String.translate convert_to_number str
(* Convert into a big number *)
val number = valOf (IntInf.fromString str)
in
IntInf.mod (number, 97) = 1
end
end handle Subscript => false | Domain => false</lang>

{{output}}
<pre>- verify_iban "GB82 WEST 1234 5698 7654 32";
val it = true : bool
- verify_iban "GB82 TEST 1234 5698 7654 32";
val it = false : bool</pre>


=={{header|Tcl}}==
=={{header|Tcl}}==