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 }