-- implementation of Luhn's checksum algorithm, computing and checking of checksum digit local luhn = {} -- main part of the algorithm, double each 2 digits, clamp them and return the sum. function luhn:_sum_digits(num) assert(num >= 0, "number must be positive") local sum = 0 local digits_n = 0 repeat -- iterate over digits from right to left local tmp = num % 10 -- get current unit -- each 2 digits, double the current digit if (digits_n % 2) == 0 then tmp = tmp * 2 end if tmp > 9 then tmp = tmp - 9 end digits_n = digits_n + 1 sum = sum + tmp -- remove unit from number num = math.floor(num / 10) until num == 0 return sum end -- returns the computed check digit function luhn:compute_check_digit(num) return (self:_sum_digits(num) * 9) % 10 end -- returns true if its valid, false otherwise function luhn:validate_check_digit(num) local check_digit = num % 10 -- get check digit return self:compute_check_digit(math.floor(num / 10)) == check_digit end -- returns the original number with the check digit concatenated at the end function luhn:make_number(num) return ((num * 10) + self:compute_check_digit(num)) end return luhn