Skip to content

Instantly share code, notes, and snippets.

@lipchyk
Created August 1, 2014 08:04
Show Gist options
  • Select an option

  • Save lipchyk/1d768be8231df22048e7 to your computer and use it in GitHub Desktop.

Select an option

Save lipchyk/1d768be8231df22048e7 to your computer and use it in GitHub Desktop.
module Luhn
extend self
def valid_cc?(num)
sum(num) % 10 == 0
end
def string_with_check_number(string)
sum = sum(string, true)
"#{string}#{check_digit(sum)}"
end
private
def check_digit(sum)
10 - sum % 10
end
def sum(num, includes_check_number = false)
digits = split(num)
digits.reverse.each_slice(2).inject(0) do |sum, d|
d1, d2 = d[0].to_i, d[1].to_i
if includes_check_number
# swap
d1, d2 = d2, d1
end
d2 = d2 * 2
d2 -= 9 if d2 > 9
sum += d1 + d2
end
end
def split(num)
num.to_s.split('').map(&:to_i)
end
end
########################################################################################
# unit tests
require 'test/unit'
class TestLuhn < Test::Unit::TestCase
# http://www.paypalobjects.com/en_US/vhelp/paypalmanager_help/credit_card_numbers.htm
def test_valid_cc?
assert_equal(true, Luhn.valid_cc?(5105105105105100))
assert_equal(true, Luhn.valid_cc?(4111111111111111))
assert_equal(true, Luhn.valid_cc?(4222222222222))
assert_equal(true, Luhn.valid_cc?(378282246310005))
assert_equal(false, Luhn.valid_cc?(42222222222))
end
def test_string_with_check_number
assert_equal('79927398713', Luhn.string_with_check_number('7992739871'))
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment