How to resolve the algorithm IBAN step by step in the F# programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm IBAN step by step in the F# programming language

Table of Contents

Problem Statement

The   International Bank Account Number (IBAN)   is an internationally agreed means of identifying bank accounts across national borders with a reduced risk of propagating transcription errors. The IBAN consists of up to 34 alphanumeric characters:

The check digits enable a sanity check of the bank account number to confirm its integrity even before submitting a transaction.

Validate the following fictitious IBAN:   GB82 WEST 1234 5698 7654 32

Details of the algorithm can be found on the Wikipedia page.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm IBAN step by step in the F# programming language

Source code in the fsharp programming language

open System
open System.Text.RegularExpressions

// A little utility to thread a negative test result (Option.None) through a
// pipeline of tests
let inline (|~>) valOption proc =
    match valOption with
    | Some(value) -> proc value
    | None -> None

[<EntryPoint>]
let main argv =
    let iban = if argv.Length = 0 then "" else argv.[0]
    iban
    |> (fun iban ->     // Check for illegal characters
            if Regex.IsMatch(iban, @"[^0-9A-Za-z ]") then None else Some(iban.ToUpper().Replace(" ", "")))
    |~> (fun iban ->    // Check length per country code
            let lengthPerCountry =
                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);
                ]
            let country = iban.Substring(0, Math.Min(2, iban.Length))
            match lengthPerCountry.TryGetValue(country) with
            | true, length ->   // country should have iban of this length
                if length = iban.Length then Some(iban) else None
            | _ -> None     // country not known
        )
    |~> (fun iban -> Some(iban.Substring(4) + iban.Substring(0,4)))
    |~> (fun iban ->
            let replaceBase36LetterWithBase10String (s : string) (c :char) = s.Replace(c.ToString(), ((int)c - (int)'A' + 10).ToString())
            Some(List.fold replaceBase36LetterWithBase10String iban [ 'A' .. 'Z' ]))
    |~> (fun iban ->    // iban mod 97
            // We could have used BigInteger, but with a loop by 7 char each 
            // over the long digit string we get away with Int32 arithmetic
            // (as described in the Wikipedia article)
            let reduceOnce r n = Int32.Parse(r.ToString() + n) % 97
            let rest =
                Regex.Matches(iban.Substring(2), @"\d{1,7}") |> Seq.cast |> Seq.map (fun x -> x.ToString())
                |> Seq.fold reduceOnce (reduceOnce 0 (iban.Substring(0,2)))
            // an iban needs a rest of 1
            if rest = 1 then Some(1) else None
        )
    |> function | Some(_) -> "a valid IBAN" | None -> "an invalid IBAN"
    |> printfn "%s is %s" iban
    0


  

You may also check:How to resolve the algorithm Tree traversal step by step in the Miranda programming language
You may also check:How to resolve the algorithm Sort disjoint sublist step by step in the AppleScript programming language
You may also check:How to resolve the algorithm Function definition step by step in the Cowgol programming language
You may also check:How to resolve the algorithm Substring/Top and tail step by step in the JavaScript programming language
You may also check:How to resolve the algorithm Create a file step by step in the ERRE programming language