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