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}}== |