Created
March 6, 2013 20:37
-
-
Save jgaskins/5102842 to your computer and use it in GitHub Desktop.
Ruby implementation of the Luhn checksum algorithm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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