On Apr 27, 6:59 pm, Ruby Quiz <j... / grayproductions.net> wrote: > The three rules of Ruby Quiz: > > 1. Please do not post any solutions or spoiler discussion for this quiz until > 48 hours have passed from the time on this message. > > 2. Support Ruby Quiz by submitting ideas as often as you can: > > http://www.rubyquiz.com/ > > 3. Enjoy! > > Suggestion: A [QUIZ] in the subject of emails about the problem helps everyone > on Ruby Talk follow the discussion. Please reply to the original quiz message, > if you can. > > -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- =-=-=-=-= > > Before a credit card is submitted to a financial institution, it generally makes > sense to run some simple reality checks on the number. The numbers are a good > length and it's common to make minor transcription errors when the card is not > scanned directly. > > The first check people often do is to validate that the card matches a known > pattern from one of the accepted card providers. Some of these patterns are: > > +============+=============+===============+ > | Card Type | Begins With | Number Length | > +============+=============+===============+ > | AMEX | 34 or 37 | 15 | > +------------+-------------+---------------+ > | Discover | 6011 | 16 | > +------------+-------------+---------------+ > | MasterCard | 51-55 | 16 | > +------------+-------------+---------------+ > | Visa | 4 | 13 or 16 | > +------------+-------------+---------------+ > > All of these card types also generate numbers such that they can be validated by > the Luhn algorithm, so that's the second check systems usually try. The steps > are: > > 1. Starting with the next to last digit and continuing with every other > digit going back to the beginning of the card, double the digit > 2. Sum all doubled and untouched digits in the number > 3. If that total is a multiple of 10, the number is valid > > For example, given the card number 4408 0412 3456 7893: > > Step 1: 8 4 0 8 0 4 2 2 6 4 10 6 14 8 18 3 > Step 2: 8+4+0+8+0+4+2+2+6+4+1+0+6+1+4+8+1+8+3 = 70 > Step 3: 70 % 10 == 0 > > Thus that card is valid. > > Let's try one more, 4417 1234 5678 9112: > > Step 1: 8 4 2 7 2 2 6 4 10 6 14 8 18 1 2 2 > Step 2: 8+4+2+7+2+2+6+4+1+0+6+1+4+8+1+8+1+2+2 = 69 > Step 3: 69 % 10 != 0 > > That card is not valid. > > This week's Ruby Quiz is to write a program that accepts a credit card number as > a command-line argument. The program should print the card's type (or Unknown) > as well a Valid/Invalid indication of whether or not the card passes the Luhn > algorithm. Here is my solution. #!/usr/bin/ruby credit_card_number = ARGV.join case when (credit_card_number=~/^(34|37)\d{13}$/): print 'AMEX ' when (credit_card_number=~/^6011\d{12}$/): print 'Discover ' when (credit_card_number=~/^5[1-5]\d{14}$/): print 'MasterCard ' when (credit_card_number=~/^4(\d{12}|\d{15})$/): print 'Visa ' else print 'Unknown ' end i = 0 luhl_number = '' credit_card_number.reverse.each_byte {|char| if (i%2==1) then char = (char.chr.to_i * 2).to_s else char = char.chr end luhl_number = char + luhl_number i += 1 } sum_total = 0 luhl_number.each_byte {|char| sum_total += char.chr.to_i } if (sum_total%10==0) then print "Valid\n" else print "Invalid\n" end