Skip to content

Instantly share code, notes, and snippets.

@Sutto
Forked from thomasfedb/luhn.rb
Created December 16, 2010 03:10
Show Gist options
  • Save Sutto/742975 to your computer and use it in GitHub Desktop.
Save Sutto/742975 to your computer and use it in GitHub Desktop.
def luhn_valid?(number)
return unless number.is_a?(String)
# Convert to a reversed list of digits
digits = number.scan(/\d/).map(&:to_i).reverse
# No numbers in the string
return false if digits.empty?
check_digit = digits.shift
# For each of the normal integers, compute the correct sum
final_digits = []
digits.each_with_index do |value, index|
# Second from the left is double.
if index.even?
final_digits << (value * 2).to_s.split('').map(&:to_i)
else
final_digits << value
end
end
# Actually compute the product, including check digit.
(final_digits.flatten.inject(:+) + check_digit) % 10 == 0
end
puts "#{luhn_valid?('4111 1111 1111 1111')} should be true"
puts "#{luhn_valid?('5500 0000 0000 0004')} should be true"
puts "#{luhn_valid?('3400 0000 0000 009')} should be true"
puts "#{luhn_valid?('3000 0000 0000 04')} should be true"
puts "#{luhn_valid?('3000 0000 0000 04')} should be true"
puts "#{luhn_valid?('6011 0000 0000 0004')} should be true"
puts "#{luhn_valid?('2014 0000 0000 009')} should be true"
puts "#{luhn_valid?('3088 0000 0000 0009')} should be true"
puts "#{luhn_valid?('3088 0000 0000 0008')} should be false"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment