2

所以我正在用 VbScript 编写一个应用程序,并且我正在尝试验证一个 IBAN 号码。但问题是,我必须修改的数字太大了。

例如:734027177486111478 mod 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

关于如何做到这一点的任何想法?

提前致谢!

4

2 回答 2

4

如果您需要更广泛的功能(受 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://stackoverflow.com/users/872583/bonsvr)
' Inspired by : schnouki http://stackoverflow.com/users/113325/schnouki

On Error GoTo CatchError

Dim objRegExp As Object
Dim IBANformat As Boolean
Dim IBANNR As String
Dim ReplaceChr As String
Dim ReplaceBy As String
Dim LeftOver As Long
Dim digit As Integer
Dim i 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 i = 10 To 35
        ReplaceChr = Chr(i + 55)
        ReplaceBy = Trim(str(i))
        IBANNR = Replace(IBANNR, ReplaceChr, ReplaceBy)
    Next i

    '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 - 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

        '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 If

End Function
于 2013-07-02T12:54:19.513 回答
3

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,看起来是正确的。

于 2013-04-11T07:55:48.510 回答