Skip to content

Instantly share code, notes, and snippets.

@cimnine
Last active July 29, 2021 22:01
Show Gist options
  • Save cimnine/7913819 to your computer and use it in GitHub Desktop.
Save cimnine/7913819 to your computer and use it in GitHub Desktop.
Luhn Algorithm in VBA (for example for use in Excel)
' Version 1.0.0
' You may use these functions directly in Excel: "=luhnCheck(A55)"
' probably only needed internally
Function luhnSum(InVal As String) As Integer
Dim evenSum As Integer
Dim oddSum As Integer
evenSum = 0
oddSum = 0
Dim strLen As Integer
strLen = Len(InVal)
Dim i As Integer
For i = strLen To 1 Step -1
Dim digit As Integer
digit = CInt(Mid(InVal, i, 1))
If ((i Mod 2) = 0) Then
oddSum = oddSum + digit
Else
digit = digit * 2
If (digit > 9) Then
digit = digit - 9
End If
evenSum = evenSum + digit
End If
Next i
luhnSum = (oddSum + evenSum)
End Function
' for the curious
Function luhnCheckSum(InVal As String)
luhnCheckSum = luhnSum(InVal) Mod 10
End Function
' true/false check
Function luhnCheck(InVal As String)
luhnCheck = (luhnSum(InVal) Mod 10) = 0
End Function
' returns a number which, appended to the InVal, turns the composed number into a valid luhn number
Function luhnNext(InVal As String)
Dim luhnCheckSumRes
luhnCheckSumRes = luhnCheckSum(InVal)
If (luhnCheckSumRes = 0) Then
luhnNext = 0
Else
luhnNext = ((10 - luhnCheckSumRes))
End If
End Function
@yakit4k0
Copy link

yakit4k0 commented Jul 12, 2017

Hello,
Using Excel 2016, Getting #VALUE! with Function luhnNext(InVal As String),
after I change the code to luhnCheckSumRes = luhnCheckSum(InVal*10) (suggested by Voidfae) and result of InVal*10 has more than 15 digits

I'm new to Excel & VBA & programming but a google search shows me that's because of floating point?

After a few try, since Function luhnNext(InVal As String) is As String,
instead of change the line to luhnCheckSumRes = luhnCheckSum(InVal*10),
I'm keeping it untouched, but add a new InVal = InVal + "0" line above that, seems working now.
Is this the right way to do it?

@rifat-f
Copy link

rifat-f commented Aug 9, 2019

The doubling is alternating, so why not just use a flag to alternate. This way it doesn't matter if the length of InVal is even or odd

    Dim i As Integer
    Dim ToDouble As Boolean
    For i = strLen To 1 Step -1
        Dim digit As Integer
        digit = CInt(Mid(InVal, i, 1))

        ToDouble  = Not ToDouble 
 
        If Not ToDouble Then
            oddSum = oddSum + digit
        Else
            digit = digit * 2
        

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment