diff --git a/luhn.go b/luhn.go index 27bbf7a..300b68a 100644 --- a/luhn.go +++ b/luhn.go @@ -2,7 +2,6 @@ package luhn import ( "fmt" - "strconv" ) type luhnNumber struct { @@ -16,14 +15,13 @@ func (l luhnNumber) calculateCheckDigit() (luhnNumber, error) { return l, fmt.Errorf("invalid input: number must be positive") } - strNumbers := strconv.FormatInt(l.baseNumber, 10) + temp := l.baseNumber var total int + multiplier := 0 - for i, multiplier := len(strNumbers)-1, 0; i >= 0; i-- { - digit, err := strconv.Atoi(string(strNumbers[i])) - if err != nil { - return l, fmt.Errorf("invalid digit at position %d: %v", i, err) - } + for temp > 0 { + digit := int(temp % 10) + temp /= 10 if multiplier%2 == 0 { digit *= 2 @@ -53,12 +51,8 @@ func FullNumber(number int64) (int64, error) { return 0, fmt.Errorf("failed to generate check digit: %v", err) } - strNumbers := strconv.FormatInt(number, 10) + strconv.Itoa(res.checkDigit) - - finalNumber, err := strconv.ParseInt(strNumbers, 10, 64) - if err != nil { - return 0, fmt.Errorf("failed to parse final number: %v", err) - } + // Append check digit arithmetically + finalNumber := number*10 + int64(res.checkDigit) return finalNumber, nil } @@ -79,16 +73,12 @@ func CheckDigit(number int64) (int, error) { // IsValid checks if the number is valid according to the Luhn algorithm func IsValid(number int64) bool { - s := strconv.FormatInt(number, 10) - if len(s) < 2 { + if number < 10 { return false } - baseNumberStr := s[:len(s)-1] - checkDigitStr := s[len(s)-1:] - - baseNumber, _ := strconv.ParseInt(baseNumberStr, 10, 64) - checkDigit, _ := strconv.Atoi(checkDigitStr) + checkDigit := int(number % 10) + baseNumber := number / 10 ln := luhnNumber{ baseNumber: baseNumber, diff --git a/luhn_test.go b/luhn_test.go index ef05808..867e4d1 100644 --- a/luhn_test.go +++ b/luhn_test.go @@ -87,3 +87,21 @@ func TestLuhnAlgorithm(t *testing.T) { }) } } + +func BenchmarkCheckDigit(b *testing.B) { + for i := 0; i < b.N; i++ { + CheckDigit(7992739871) + } +} + +func BenchmarkFullNumber(b *testing.B) { + for i := 0; i < b.N; i++ { + FullNumber(7992739871) + } +} + +func BenchmarkIsValid(b *testing.B) { + for i := 0; i < b.N; i++ { + IsValid(79927398713) + } +}