Here is my solution a bit schoolboyish :-(
BEGIN : quiz122.rb-------------------------------------------------------------------------------#!/usr/bin/ruby
def is_luhn? cardno
digits = cardno.split(//).reverse!
sum = '' digits.each_index do |i| if i%2 == 0 sum << digits[i] else sum << (2 * digits[i].to_i).to_s end
end s1 = 0 sum.split(//).inject(s1) { |s1, v| s1 += v.to_i } if s1 % 10 == 0 return "Valid" else return "InValid" end
end
if __FILE__ == $0:
abort("Usage: ruby quiz122.rb #CARDNO") if ARGV.length != 1
cardno = ARGV[0].gsub(/[^0-9]/, '')
is_luhn? cardno
print "card number \"#{cardno}\" is " case cardno.length when 13 if cardno.match(/^4/) print "Visa : " else print "Unknown : " end puts is_luhn?(cardno)
when 14 if cardno.match(/(^30[0-2][0-9])|(^30[4-5][0-9])|(^36)|(^38(1[5-9]|[2-9]))/) print "Diners : " else print "Unknown : " end
when 15 if cardno.match(/^3(4|7)/) print "Amex : " else print "Unknown : " end
when 16 if cardno.match(/^6011/) print "Discover : " elsif cardno.match(/^4/) print "Visa : " elsif cardno.match(/^5[1-5]/) print "MasterCard : " elsif cardno.match(/^35(2[8-9]|[3-8][0-9])/) print "JCB : " else print "Unknown : " end
else print "Unknown : "
end
puts is_luhn?(cardno) + " CC "
end------------------------------------------------------------------------------
On 4/27/07, Ruby Quiz <james / 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.>>
--
[ written in http://www.paahijen.com/scratchpad ]
[ http://www.paahijen.com ]