Task: IBAN





Java: import java.math.BigInteger;
import java.util.*;

public class IBAN {
    private static final String DEFSTRS = ""
            + "AL28 AD24 AT20 AZ28 BE16 BH22 BA20 BR29 BG22 "
            + "HR21 CY28 CZ24 DK18 DO28 EE20 FO18 FI18 FR27 GE22 DE22 GI23 "
            + "GL18 GT28 HU28 IS26 IE22 IL23 IT27 KZ20 KW30 LV21 LB28 LI21 "
            + "LT20 LU20 MK19 MT31 MR27 MU30 MC27 MD24 ME22 NL18 NO15 PK24 "
            + "PS29 PL28 PT25 RO24 SM27 SA24 RS22 SK24 SI19 ES24 SE24 CH21 "
            + "TN24 TR26 AE23 GB22 VG24 GR27 CR21";
    private static final Map<String, Integer> DEFINITIONS = new HashMap<>();

    static {
        for (String definition : DEFSTRS.split(" "))
            DEFINITIONS.put(definition.substring(0, 2), Integer.parseInt(definition.substring(2)));
    }

    public static void main(String[] args) {
        String[] ibans = {
                "GB82 WEST 1234 5698 7654 32",
                "GB82 TEST 1234 5698 7654 32",
                "GB81 WEST 1234 5698 7654 32",
                "SA03 8000 0000 6080 1016 7519",
                "CH93 0076 2011 6238 5295 7",
                "XX00 0000",
                "",
                "DE",
                "DE13 äöü_ 1234 1234 1234 12"};
        for (String iban : ibans)
            System.out.printf("%s is %s.%n", iban, validateIBAN(iban) ? "valid" : "not valid");
    }

    static boolean validateIBAN(String iban) {
        iban = iban.replaceAll("\\s", "").toUpperCase(Locale.ROOT);

        int len = iban.length();
        if (len < 4 || !iban.matches("[0-9A-Z]+") || DEFINITIONS.getOrDefault(iban.substring(0, 2), 0) != len)
            return false;

        iban = iban.substring(4) + iban.substring(0, 4);

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < len; i++)
            sb.append(Character.digit(iban.charAt(i), 36));

        BigInteger bigInt = new BigInteger(sb.toString());

        return bigInt.mod(BigInteger.valueOf(97)).intValue() == 1;
    }
}




VB: Public nations As New Collection
Private Sub init()
    nations.Add 24, "AD"
    nations.Add 21, "CH"
    nations.Add 22, "GB"
    nations.Add 24, "SA"
    nations.Add 20, "XK"
End Sub

Private Function mod97(ByVal c As String) As Integer
    Dim n As Long
    n = Val(Mid(c, 1, 9))
    c = Mid(c, 10, Len(c) - 9)
    n = n Mod 97
    Do While Len(c) > 6
        n = Val(Str(n) & Mid(c, 1, 7))
        n = n Mod 97
        c = Mid(c, 8, Len(c) - 7)
    Loop
    n = Val(Str(n) & c)
    mod97 = n Mod 97
End Function

Private Function iban(ByVal code As String) As Boolean


    On Error GoTo 1
    lengths = nations(Mid(code, 1, 2))
    If Len(code) = lengths Then
        code = code & Mid(code, 1, 4)
        code = Mid(code, 5, lengths)
        Dim c As String: c = ""
        Dim ch As String
        For i = 1 To lengths
            ch = Mid(code, i, 1)
            If ch >= "0" And ch <= "9" Then
                c = c & ch
            Else
                If ch >= "A" And ch <= "Z" Then
                    c = c & Str(Asc(ch) - 55)
                Else
                    iban = False
                End If
            End If
        Next i
        c = Replace(c, " ", "")
        iban = mod97(c) = 1
    End If
    Exit Function
1:
    iban = False
End Function
 
Private Function iban_s(code As String) As Boolean

    code = Replace(code, " ", "")
    code = Replace(code, "-", "")
    iban_s = iban(code)
End Function
 
Private Sub test(code As String, expected As Boolean)
    Dim valid As Boolean
    valid = iban_s(code)
    Dim state As String
    If valid = expected Then
        state = IIf(valid, "ok", "invalid (as expected)")
    Else
        state = IIf(valid, "OK!!", "INVALID!!") & " (NOT AS EXPECTED)"
    End If
    Debug.Print code, state
End Sub

Public Sub main()
    init
    test "GB82 WEST 1234 5698 7654 32", True
    test "GB82 TEST 1234 5698 7654 32", False
    test "GB81 WEST 1234 5698 7654 32", False
    test "SA03 8000 0000 6080 1016 7519", True
    test "CH93 0076 2011 6238 5295 7", True
End Sub