59 lines
1.1 KiB
Go
59 lines
1.1 KiB
Go
package luhn
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"strconv"
|
|
)
|
|
|
|
// Valid takes a numeric string and returns whether
|
|
// it's Luhn valid.
|
|
func Valid(toCheck string) bool {
|
|
return GetRemainder(toCheck) == 0
|
|
}
|
|
|
|
// GetRemainder returns the leftover from
|
|
// running a number through the Luhn checker
|
|
func GetRemainder(toCheck string) int {
|
|
// Remove any non-numeric characters
|
|
r := regexp.MustCompile("[^0-9]+")
|
|
toCheck = r.ReplaceAllString(toCheck, "")
|
|
|
|
if len(toCheck) == 0 {
|
|
return -1
|
|
}
|
|
var total int
|
|
var double bool
|
|
for i := range toCheck {
|
|
var add int
|
|
var err error
|
|
idx := (len(toCheck) - 1) - i
|
|
if add, err = strconv.Atoi(string(toCheck[idx])); err != nil {
|
|
return -1
|
|
}
|
|
if double {
|
|
add = add * 2
|
|
if add >= 10 {
|
|
add = add - 9
|
|
}
|
|
}
|
|
double = !double
|
|
total += add
|
|
}
|
|
return total % 10
|
|
}
|
|
|
|
// AddCheck takes a number and returns the appropriate
|
|
// number with an added digit that makes it valid
|
|
func AddCheck(toCheck string) string {
|
|
if GetRemainder(toCheck) != 0 {
|
|
for i := 0; i <= 9; i++ {
|
|
tst := fmt.Sprintf("%s%d", toCheck, i)
|
|
if GetRemainder(tst) == 0 {
|
|
return tst
|
|
}
|
|
}
|
|
}
|
|
return toCheck
|
|
}
|