VbScript проверяет IBAN с помощью mod97 (число слишком велико)

Поэтому я пишу приложение на VbScript и пытаюсь проверить номер IBAN. Проблема, однако, число, с которым я должен мод, слишком велико.

Например: 734027177486111478 мод 97

это то, что я хочу сделать, но я не могу найти тип, который можно использовать для этого. Ниже приведен код, который я использую в данный момент. В этом примере vCheckCode в последней точке - 734027177486111478.

Function checkIBAN(ByVal vIban)
vLandcode = Mid(vIban, 1, 2)    

Select Case vLandcode
    Case "BE"
        vIban = Replace(vIban, " ", "")

        If Len(vIban) = 16 Then
            vPrefix = Mid(vIban, 1, 4)
            vCheckCode = Replace(vIban, vPrefix, "")
            vSuffix = Replace(vPrefix, "BE", "1114")
            vCheckCode = vCheckCode + vSuffix
            vCheckCode = CDbl(vCheckCode)
            vResult = vCheckCode Mod 97             
        End If
End Select
End Function

Есть идеи, как это сделать?

Заранее спасибо!

2 ответа

Решение

734027177486111478 слишком большой, чтобы быть представленным как 32-разрядное целое число, поэтому вы не можете просто использовать Mod 97 как это.

Простое решение состоит в использовании некоторой базовой математики:

  • (a + b) mod n = ((a mod n) + (b mod n)) mod n
  • (a * b) mod n = ((a mod n) * (b mod n)) mod n

И из этого вы можете вычислить ваш модуль по цифре за цифрой:

Function Mod97(ByVal vIban)
    Dim i, m, digit
    m = 0
    For i = 1 To Len(vIban)
        digit = CInt(Mid(vIban, i, 1))
        m = (10*m + digit) Mod 97
    Next
    Mod97 = m
End Function

Mod97("734027177486111478") возвращает 1, что выглядит правильно.

Если вам нужно, чтобы функция была немного шире (вдохновлено Schnouki):

Public Function VALIDATEIBAN(ByVal IBAN As String) As String

' Created by : Koen Rijnsent (www.castoro.nl)
' Inspired by : Chris Fannin (AbbydonKrafts)
' Inspired by : bonsvr (http://stackru.com/users/872583/bonsvr)
' Inspired by : schnouki http://stackru.com/users/113325/schnouki

On Error GoTo CatchError
DoEvents

Dim objRegExp As Object
Dim IBANformat As Boolean
Dim IBANNR As String
Dim ReplaceChr As String
Dim ReplaceBy As String
Dim LeftOver As Long

'Base format clean - uppercase and remove spaces
IBAN = Replace(UCase(IBAN), " ", "")
'Check format, length 15-31 characters, first countrycode, then two digits, then number
Set objRegExp = CreateObject("vbscript.regexp")
objRegExp.IgnoreCase = True
objRegExp.Global = True
objRegExp.Pattern = "[a-zA-Z]{2}[0-9]{2}[a-zA-Z0-9]{11}([a-zA-Z0-9]?){0,16}"
IBANformat = objRegExp.Test(IBAN)

'Validity of country code will not be checked!
If IBANformat = False Then
    VALIDATEIBAN = "FORMAT NOT RECOGNIZED"
Else
    'Flip first 4 characters to the back
    IBANNR = Right(IBAN, Len(IBAN) - 4) & Left(IBAN, 4)

    'Replace letters by the right numbers
    For Nr = 10 To 35
        ReplaceChr = Chr(Nr + 55)
        ReplaceBy = Trim(Str(Nr))
        IBANNR = Replace(IBANNR, ReplaceChr, ReplaceBy)
    Next Nr

    'Loop through the IBAN, as it is too long to calculate at one go
    LeftOver = 0
    For i = 1 To Len(IBANNR)
        digit = CInt(Mid(IBANNR, i, 1))
        LeftOver = (10 * LeftOver + digit) Mod 97
    Next

    If LeftOver = 1 Then
        If Len(IBAN) = IBANLEN(Left(IBAN, 2)) Then
            VALIDATEIBAN = "IBAN OK"
        ElseIf IBANLEN(Left(IBAN, 2)) = 0 Then
            VALIDATEIBAN = "COUNTRYCODE UNKNOWN, 97 CHECK OK"
        Else
            VALIDATEIBAN = "LENGTH INVALID WITH COUNTRYCODE"
        End If
    Else
        VALIDATEIBAN = "97 CHECK FAILED"
    End If
End If

Exit Function

CatchError:
    VALIDATEIBAN = "ERROR: " & Err.Description
    MsgBox "Module: " & MODULE_NAME & " - VALIDATEIBAN function" & vbCrLf & vbCrLf _
    & "Error#:  " & Err.Number & vbCrLf & vbCrLf & Err.Description

End Function

И функция для кода страны / длины:

Function IBANLEN(CountryCode As String) As Integer

    ' Created by : Koen Rijnsent (www.castoro.nl)
    If Len(CountryCode) <> 2 Then
        IBANLEN = 0
    Else
    End If

    'List of country codes, based on http://en.wikipedia.org/wiki/International_Bank_Account_Number
    Select Case CountryCode
    Case "AL"
       IBANLEN = 28
    Case "AD"
       IBANLEN = 24
    Case "AE"
       IBANLEN = 23
    Case "AO"
       IBANLEN = 25
    Case "AT"
       IBANLEN = 20
    Case "AZ"
       IBANLEN = 28
    Case "BH"
       IBANLEN = 22
    Case "BE"
       IBANLEN = 16
    Case "BA"
       IBANLEN = 20
    Case "BF"
       IBANLEN = 27
    Case "BI"
       IBANLEN = 16
    Case "BJ"
       IBANLEN = 28
    Case "BR"
       IBANLEN = 29
    Case "BG"
       IBANLEN = 22
    Case "CH"
       IBANLEN = 21
    Case "CI"
       IBANLEN = 28
    Case "CM"
       IBANLEN = 27
    Case "CR"
       IBANLEN = 21
    Case "CV"
       IBANLEN = 25
    Case "CY"
       IBANLEN = 28
    Case "CZ"
       IBANLEN = 24
    Case "DE"
       IBANLEN = 22
    Case "DK"
       IBANLEN = 18
    Case "DO"
       IBANLEN = 28
    Case "EE"
       IBANLEN = 20
    Case "ES"
       IBANLEN = 24
    Case "FO"
       IBANLEN = 18
    Case "FI"
       IBANLEN = 18
    Case "FR"
       IBANLEN = 27
    Case "GB"
       IBANLEN = 22
    Case "GE"
       IBANLEN = 22
    Case "GI"
       IBANLEN = 23
    Case "GR"
       IBANLEN = 27
    Case "GL"
       IBANLEN = 18
    Case "GT"
       IBANLEN = 28
    Case "HR"
       IBANLEN = 21
    Case "HU"
       IBANLEN = 28
    Case "IE"
       IBANLEN = 22
    Case "IL"
       IBANLEN = 23
    Case "IR"
       IBANLEN = 26
    Case "IS"
       IBANLEN = 26
    Case "IT"
       IBANLEN = 27
    Case "KZ"
       IBANLEN = 20
    Case "KW"
       IBANLEN = 30
    Case "LB"
       IBANLEN = 28
    Case "LI"
       IBANLEN = 21
    Case "LT"
       IBANLEN = 20
    Case "LU"
       IBANLEN = 20
    Case "LV"
       IBANLEN = 21
    Case "MC"
       IBANLEN = 27
    Case "MD"
       IBANLEN = 24
    Case "ME"
       IBANLEN = 22
    Case "MG"
       IBANLEN = 27
    Case "MK"
       IBANLEN = 19
    Case "ML"
       IBANLEN = 28
    Case "MT"
       IBANLEN = 31
    Case "MR"
       IBANLEN = 27
    Case "MU"
       IBANLEN = 30
    Case "MZ"
       IBANLEN = 25
    Case "NL"
       IBANLEN = 18
    Case "NO"
       IBANLEN = 15
    Case "PK"
       IBANLEN = 24
    Case "PS"
       IBANLEN = 29
    Case "PL"
       IBANLEN = 28
    Case "PT"
       IBANLEN = 25
    Case "RO"
       IBANLEN = 24
    Case "RS"
       IBANLEN = 22
    Case "SA"
       IBANLEN = 24
    Case "SE"
       IBANLEN = 24
    Case "SI"
       IBANLEN = 19
    Case "SK"
       IBANLEN = 24
    Case "SM"
       IBANLEN = 27
    Case "SN"
       IBANLEN = 28
    Case "TN"
       IBANLEN = 24
    Case "TR"
       IBANLEN = 26
    Case "UA"
       IBANLEN = 29
    Case "VG"
       IBANLEN = 24
    Case Else
        IBANLEN = 0
    End Select

End Function
Другие вопросы по тегам