Sunday 26 May 2019

VBA - Luhn Algorithm

I'm not the world's greatest cryptographer but I am surprised how easy the 16-digit credit card number is to generate, I guess the guy (Luhn) who invented it in the 1950s had little computing power. Below is some code to check a credit card number. Further below is some code to generate your own. For test data generation purposes only, no nefarious uses please.

Option Explicit

Public Function Check(ByVal ccNumber As String)
    '* VBA implementation of Luhn algorithm
    '* Based on a Java class from
    '* https://stackoverflow.com/questions/20740444/check-credit-card-validity-using-luhn-algorithm#answer-27326507
    Dim sum As Long
    Dim alternate As Boolean
    Dim i As Long
    For i = Len(ccNumber) To 1 Step -1
        Dim n As Long
        n = CLng(Mid$(ccNumber, i, 1))
        If alternate Then
            n = n * 2
            If (n > 9) Then
                n = (n Mod 10) + 1
            End If
        End If
        sum = sum + n
        alternate = Not alternate
    Next

    Check = (sum Mod 10 = 0)

End Function

Sub TestCheck()
    '* not mine from SO https://stackoverflow.com/questions/20725761/validate-credit-card-number-using-luhn-algorithm
    Debug.Assert Check("4388576018410707")
End Sub
    
Sub GenerateTestData()
    Dim lLoop As Long
    
    Dim sStem As String
    sStem = Left("4388576018410707", 1)
    
    Dim sWork As String
    sWork = sStem
    
    Dim lDigitsToGenerate As Long
    lDigitsToGenerate = 16 - Len(sWork)
    
    Dim lRandomDigits As Long
    lRandomDigits = lDigitsToGenerate - 1
    
    For lLoop = 1 To lRandomDigits
        sWork = sWork & CStr((CInt(Rnd(1) * 10) Mod 10))
    Next lLoop
    
    Debug.Assert Len(sWork) = 15
    
    For lLoop = 0 To 9
        Dim sTry As String
        sTry = sWork & CStr(lLoop)
        
        Debug.Assert Len(sTry) = 16
        
        If Check(sTry) Then
            Debug.Print sTry
            Exit For
        End If
    Next
    
End Sub

No comments:

Post a Comment