Skip to content

Instantly share code, notes, and snippets.

@dsingley
Last active December 14, 2015 11:09
Show Gist options
  • Save dsingley/5077353 to your computer and use it in GitHub Desktop.
Save dsingley/5077353 to your computer and use it in GitHub Desktop.
Ruby class implementing H. Michael Damm's check digit algorithm
class DammAlgorithm
# http://en.wikipedia.org/wiki/Damm_algorithm
TABLE = [ [0, 7, 4, 1, 6, 3, 5, 8, 9, 2],
[3, 0, 2, 7, 1, 6, 8, 9, 4, 5],
[1, 9, 0, 5, 2, 7, 6, 4, 3, 8],
[7, 2, 6, 0, 3, 4, 9, 5, 8, 1],
[5, 1, 8, 9, 0, 2, 7, 3, 6, 4],
[9, 5, 7, 8, 4, 0, 2, 6, 1, 3],
[8, 4, 1, 3, 5, 9, 0, 2, 7, 6],
[6, 8, 3, 4, 9, 5, 1, 0, 2, 7],
[4, 6, 5, 2, 7, 8, 3, 1, 0, 9],
[2, 3, 9, 6, 8, 1, 4, 7, 5, 0]
]
def self.calculate_digit(str_or_int)
interim_digit = 0
digits(str_or_int).each do |digit|
interim_digit = TABLE[digit][interim_digit]
end
interim_digit
end
def self.calculate(str_or_int)
with_check_digit = str_or_int.to_i * 10 + calculate_digit(str_or_int)
str_or_int.kind_of?(Integer) ? with_check_digit : with_check_digit.to_s.rjust(str_or_int.length + 1, '0')
end
def self.validate(str_or_int)
calculate_digit(str_or_int) == 0
end
private
def self.digits(str_or_int)
str_or_int.to_s.gsub(/\D/, '').sub(/^0+/, '').to_s.chars.map {|c| c.to_i}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment