# \[QUIZ\] Checking Credit Cards (#122)

**URL:** <https://www.ruby-forum.com/t/quiz-checking-credit-cards-122/103009>\
**Category:** Ruby\
**Created:** [April 30, 2007, 6:40pm UTC](https://www.ruby-forum.com/t/quiz-checking-credit-cards-122/103009 "2007-04-30T18:40:05Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![mike-moscow](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/53a042/32.png) [@mike-moscow](https://www.ruby-forum.com/u/mike-moscow)\
**Post date:** [April 30, 2007, 6:40pm UTC](https://www.ruby-forum.com/t/quiz-checking-credit-cards-122/103009/1 "2007-04-30T18:40:05Z")

</div>

This is my first submission to Ruby Q…

I have all the credit card rules in an external YAML file. I also think  
that my luhn() and type() implementations could be cleaner, but it is  
what  
it is. 🙂

* * *

# ccard.yaml

Visa: { starts: [‘4’],  
sizes: [16, 13] }  
MasterCard: { starts: [‘51’, ‘52’, ‘52’, ‘54’, ‘55’],  
sizes: [16] }  
Discover: { starts: [‘6011’],  
sizes: [16] }  
American Express: { starts: [‘34’, ‘37’],  
sizes: [15] }

* * *

# ccard.rb

# Credit Card Validation

# Ruby Q. #122 - [Ruby Quiz - Checking Credit Cards (#122)](http://www.rubyquiz.com/quiz122.html)

# By Mike M. - [http://blowmage.com/](http://blowmage.com/)

require ‘yaml’

class CreditCard  
def CreditCard.luhn(cc)  
multi = 1  
nums = cc.gsub(/\D/, ‘’).reverse.split(‘’).collect do |num|  
num = num.to\_i \* (multi = (multi == 1) ? 2 : 1)  
end  
total = 0  
nums.join.split(‘’).each do |num|  
total += num.to\_i  
end  
total  
end

def CreditCard.valid?(cc)  
(CreditCard.luhn(cc) % 10) == 0  
end

def CreditCard.type(cc)  
cc.gsub!(/\D/, ‘’)  
YAML::load(open(‘ccard.yaml’)).each do |card, rule|  
rule[‘starts’].each do |start|  
if (cc.index(start.to\_s) == 0)  
return card if rule[‘sizes’].index(cc.size)  
end  
end  
end  
‘Unknown’  
end

def initialize(cc)  
@number = cc.gsub(/\D/, ‘’)  
end

def number  
@number  
end

def number=(cc)  
@number = cc.gsub(/\D/, ‘’)  
end

def valid?  
CreditCard.valid? @number  
end

def type  
CreditCard.type @number  
end  
end

if **FILE** == $0  
cc = CreditCard.new ARGV.join  
puts “You entered the following credit card number: #{cc.number}”  
puts “The number is for a #{cc.type} credit card”  
puts “The number is #{cc.valid? ? ‘Valid’ : ‘Not Valid’}”  
end
