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

**URL:** https://rubytalk.org/t/quiz-checking-credit-cards-122/37348
**Category:** ruby-talk
**Created:** [2 May 2007 18:37 UTC](https://rubytalk.org/t/quiz-checking-credit-cards-122/37348 "2007-05-02T18:37:31Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![Chase\_Southard](https://avatars.discourse-cdn.com/v4/letter/c/439d5e/32.png) [@Chase\_Southard](https://rubytalk.org/u/Chase_Southard)
#### Post date: [2 May 2007 18:37 UTC](https://rubytalk.org/t/quiz-checking-credit-cards-122/37348/1 "2007-05-02T18:37:31Z")

</div>

This is my first time submitting a solution to the quiz. I'll attach my .rb  
file and copy / paste my solution below. It's ugly, but it works.

Thanks,

Chase Southard

#!/usr/bin/env ruby

[Quiz122\_CardValidator.rb](https://rubytalk.org/uploads/short-url/nRdU089VzkyFlX5Ps7x23u9Ihdo.rb) (4.27 KB)

> **···**
>
> #  
> # Created by Chase Southard on 2007-05-01.
> 
> class CardValidator
> 
> &nbsp;&nbsp;def get\_card\_number  
> &nbsp;&nbsp;&nbsp;&nbsp;if $\*[0] == nil  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "I need a card number. Please enter one now:"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cardnumber = $stdin.gets.strip!  
> &nbsp;&nbsp;&nbsp;&nbsp;else  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cardnumber = ARGV.shift  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;puts "You entered: #{cardnumber}"  
> &nbsp;&nbsp;&nbsp;&nbsp;@card\_array = cardnumber.split(//).collect  
> &nbsp;&nbsp;&nbsp;&nbsp;#remove spaces  
> &nbsp;&nbsp;&nbsp;&nbsp;@card\_array.compact!  
> &nbsp;&nbsp;end
> 
> &nbsp;&nbsp;def validate\_card\_prefix  
> &nbsp;&nbsp;&nbsp;&nbsp;#case statement to grab the first few digits  
> &nbsp;&nbsp;&nbsp;&nbsp;case @card\_array.first.to\_i  
> &nbsp;&nbsp;&nbsp;&nbsp;when 3  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prefix = @card\_array.slice(0, 2).join.to\_i  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#debug  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#puts prefix  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#puts prefix.class  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if prefix == 34 || 37  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if @card\_array.length == 15  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;card\_type = "AMEX"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "The card type entered was: #{card\_type}"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"You might have bogus card."  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"You might have a bogus card."  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;when 6  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prefix = @card\_array.slice(0,4).join.to\_i  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#debug  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#puts prefix  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#puts prefix.class  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#puts "card length: #{@card\_array.length}"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if prefix == 6011 && @card\_array.length == 16  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;card\_type = "Discover"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "The card type entered was: #{card\_type}"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"You might have a bogus card."  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;when 4  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if @card\_array.length == 13 || 16  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;card\_type = "Visa"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "The card type entered was: #{card\_type}"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"You might have a bogus card."  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;when 5  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prefix = @card\_array.slice(0, 2).join.to\_i  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#puts prefix  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#puts prefix.class  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if prefix == 51 || 52 || 53 || 54  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if @card\_array.length == 16  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;card\_type = "MasterCard"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "The card type entered was: #{card\_type}"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"You might have a bogus card."  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;end
> 
> &nbsp;&nbsp;def validate\_luhn  
> &nbsp;&nbsp;&nbsp;&nbsp;array\_size = @card\_array.length
> 
> &nbsp;&nbsp;&nbsp;&nbsp;#starting at the LAST digit and working backwards gathering digits to  
> get the untouched elements of the card number
> 
> &nbsp;&nbsp;&nbsp;&nbsp;untouched\_elements\_index = Array.new  
> &nbsp;&nbsp;&nbsp;&nbsp;while array\_size \> 1  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;untouched\_elements\_index.push(array\_size - 1)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array\_size -= 2  
> &nbsp;&nbsp;&nbsp;&nbsp;end
> 
> &nbsp;&nbsp;&nbsp;&nbsp;untouched\_elements = Array.new  
> &nbsp;&nbsp;&nbsp;&nbsp;untouched\_elements\_index.each { |e|  
> untouched\_elements.push(@card\_array[e].to\_i) }
> 
> &nbsp;&nbsp;&nbsp;&nbsp;#reset array size for the next part  
> &nbsp;&nbsp;&nbsp;&nbsp;array\_size = @card\_array.length
> 
> &nbsp;&nbsp;&nbsp;&nbsp;#Starting at the NEXT TO LAST digit and working backwards gathering  
> digits to get the touched elements of the card number  
> &nbsp;&nbsp;&nbsp;&nbsp;every\_other\_element = Array.new  
> &nbsp;&nbsp;&nbsp;&nbsp;while array\_size \> 1  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;every\_other\_element.push(array\_size - 2)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array\_size -= 2  
> &nbsp;&nbsp;&nbsp;&nbsp;end
> 
> &nbsp;&nbsp;&nbsp;&nbsp;#debug  
> &nbsp;&nbsp;&nbsp;&nbsp;#puts "Every other element: #{every\_other\_element}"
> 
> &nbsp;&nbsp;&nbsp;&nbsp;#multiply each element by 2  
> &nbsp;&nbsp;&nbsp;&nbsp;touched\_array = Array.new  
> &nbsp;&nbsp;&nbsp;&nbsp;every\_other\_element.each { |element|  
> touched\_array.push(@card\_array[element].to\_i\*2) }
> 
> &nbsp;&nbsp;&nbsp;&nbsp;#debug  
> &nbsp;&nbsp;&nbsp;&nbsp;#puts "Touched array: #{touched\_array}"
> 
> &nbsp;&nbsp;&nbsp;&nbsp;#split each into digits  
> &nbsp;&nbsp;&nbsp;&nbsp;split\_touched\_array = Array.new  
> &nbsp;&nbsp;&nbsp;&nbsp;touched\_array.each { |e| split\_touched\_array.push(e.to\_s.split(//)) }  
> &nbsp;&nbsp;&nbsp;&nbsp;split\_touched\_array.flatten!
> 
> &nbsp;&nbsp;&nbsp;&nbsp;#debug  
> &nbsp;&nbsp;&nbsp;&nbsp;#puts "Split touched array:"  
> &nbsp;&nbsp;&nbsp;&nbsp;#puts split\_touched\_array
> 
> &nbsp;&nbsp;&nbsp;&nbsp;#return digits to integer form  
> &nbsp;&nbsp;&nbsp;&nbsp;split\_touched\_array\_integers = Array.new  
> &nbsp;&nbsp;&nbsp;&nbsp;split\_touched\_array.each { |e| split\_touched\_array\_integers.push(e.to\_i)  
> }
> 
> &nbsp;&nbsp;&nbsp;&nbsp;#debug  
> &nbsp;&nbsp;&nbsp;&nbsp;#split\_touched\_array\_total = 0  
> &nbsp;&nbsp;&nbsp;&nbsp;#split\_touched\_array\_integers.each { |e| split\_touched\_array\_total += e  
> }  
> &nbsp;&nbsp;&nbsp;&nbsp;#puts "split total = #{split\_touched\_array\_total}"
> 
> &nbsp;&nbsp;&nbsp;&nbsp;#concatentate the two arrays  
> &nbsp;&nbsp;&nbsp;&nbsp;all\_digit\_array = untouched\_elements + split\_touched\_array\_integers
> 
> &nbsp;&nbsp;&nbsp;&nbsp;#find the total value of the touched and untouched digits from the card  
> number  
> &nbsp;&nbsp;&nbsp;&nbsp;array\_total\_value = 0  
> &nbsp;&nbsp;&nbsp;&nbsp;all\_digit\_array.each { |x| array\_total\_value += x }
> 
> &nbsp;&nbsp;&nbsp;&nbsp;#debug  
> &nbsp;&nbsp;&nbsp;&nbsp;#puts "array total value = #{array\_total\_value}"
> 
> &nbsp;&nbsp;&nbsp;&nbsp;#final determination of validity by Luhn algorithm  
> &nbsp;&nbsp;&nbsp;&nbsp;@numerical\_validation = false
> 
> &nbsp;&nbsp;&nbsp;&nbsp;if array\_total\_value % 10 == 0  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@numerical\_validation = true  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "This card number, #{@card\_array}, is valid [by Luhn algorithm]"  
> &nbsp;&nbsp;&nbsp;&nbsp;else  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "This card number, #{@card\_array}, is in-valid [by Luhn  
> algorithm]"  
> &nbsp;&nbsp;&nbsp;&nbsp;end
> 
> &nbsp;&nbsp;end
> 
> end
> 
> my\_card = CardValidator.new  
> my\_card.get\_card\_number  
> my\_card.validate\_card\_prefix  
> my\_card.validate\_luhn
