Skip to content

Instantly share code, notes, and snippets.

@jgaskins
Created March 6, 2013 20:37
Show Gist options
  • Save jgaskins/5102842 to your computer and use it in GitHub Desktop.
Save jgaskins/5102842 to your computer and use it in GitHub Desktop.
Ruby implementation of the Luhn checksum algorithm
# Luhn Checksum
#
# http://en.wikipedia.org/wiki/Luhn_algorithm
#
# Implement a Ruby program that outputs the validity of a number by applying the Luhn Checksum.
#
# Input:
# The program should accept a single number to validate.
#
# Output:
# The program should output the input along with the validity of the number.
#
# Examples:
# With an input of 79927398713 the output would be:
# 79927398713 is valid.
#
# With an input of 79927398710 the output would be:
# 79927398710 is not valid.
class LuhnChecksum
attr_reader :value
def initialize(value)
@value = value
end
def valid?
(checksum % 10).zero?
end
def invalid?
!valid?
end
def checksum
modified_digits.map { |i| sum_digits(i) }.reduce(0, :+)
end
private
def sum_digits(number)
digits(number).reduce(0, :+)
end
def digits(number=value)
number.to_s.split('').map(&:to_i)
end
def modified_digits
digits.reverse.map.with_index { |i, index| (index % 2).zero? ? i : i * 2 }.reverse
end
end
# Run specs when run through the RSpec CLI
if defined? RSpec
describe LuhnChecksum do
it 'is valid for 79927398713' do
LuhnChecksum.new(79927398713).should be_valid
end
it 'is invalid for 79927398710' do
LuhnChecksum.new(79927398710).should be_invalid
end
# Common check value for credit cards
it 'is valid for 4111111111111111' do
LuhnChecksum.new(4111111111111111).should be_valid
end
end
end
# Run standalone if directly running this file.
if $0 == __FILE__
checker = LuhnChecksum.new(ARGV[0].to_i)
puts "#{checker.value} is #{'not ' if checker.invalid?}valid."
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment