Luhn check a card number
Before a card ever reaches the payment gateway, the checkout runs the Luhn checksum so an obvious typo is caught in the browser.
- Working from the right, double every second digit; if doubling gives more than 9, subtract 9.
- The number is valid when the resulting sum divides by 10.
- Spaces and dashes are formatting and are ignored.
- Any other non-digit makes it invalid, as does anything shorter than two digits.
luhnValid(digits: string) → bool
Go needs a compiler and Drill does not host one yet, so this page is the reference rather than an exercise: the problem, worked examples, and the solution in full. To type it out, the same problem runs in Python.
Where you start
func luhnValid(digits string) bool {
}
Worked examples
| Call | Result |
|---|---|
luhnValid("79927398713") | true |
luhnValid("79927398710") | false |
luhnValid("4111 1111 1111 1111") | true |
luhnValid("4111-1111-1111-1112") | false |
Hint
Strip the formatting into a clean string first. Then walk it backwards with an index so "every second" is easy to say.
Reference solution in Go
func luhnValid(digits string) bool {
clean := []byte{}
for i := 0; i < len(digits); i++ {
c := digits[i]
if c == ' ' || c == '-' {
continue
}
if c < '0' || c > '9' {
return false
}
clean = append(clean, c)
}
if len(clean) < 2 {
return false
}
sum := 0
for i := 0; i < len(clean); i++ {
d := int(clean[len(clean)-1-i] - '0')
if i%2 == 1 {
d *= 2
if d > 9 {
d -= 9
}
}
sum += d
}
return sum%10 == 0
}